First commit ~0,10

This commit is contained in:
José David Guillén 2021-09-08 21:26:43 +02:00
commit 37dffcdec3
188 changed files with 23679 additions and 0 deletions

781
BDATOS/BDATOS.CPP Normal file
View File

@ -0,0 +1,781 @@
#include <io.h>
#include <mem.h>
#include <alloc.h>
#include <string.h>
#define __BDatos_CPP
#include "c:\program\src_dos\libs\bdatos\BDatos.hh"
// ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
#define PROG_NAME "BDatos::JD::"
// ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
#define VER_HI 1
#define VER_LOW 0
#define ARCH_LEN 12
#define FALSO 0
#define CIERTO 1
typedef struct
{
char code;
long pos;
} BTree;
/**************************************************************************\
| |
| Contructor de Clase |
| |
| Descripcion: |
| Se encarga de poner a cero todas las variables utilizadas |
| |
| |
| Entradas: (ninguna) |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
BDatos::BDatos()
{
BDatosHeader.NRegistros = 0;
BDatosHeader.NRegTotal = 0;
BDatosHeader.SizeReg = 0;
BDatosHeader.VerHi = VER_HI;
BDatosHeader.VerLow = VER_LOW;
BDatosHeader.Eof_Code = 26;
strcpy( BDatosHeader.NBD, "BDatos::JD::" );
memset( BDatosHeader.MyHeader.ProgName, 32, sizeof(char)* 15 );
BDatosHeader.MyHeader.VerHi = 0;
BDatosHeader.MyHeader.VerLow = 0;
memset( BDatosHeader.MyHeader.Other, 32, sizeof(char)*200 );
NRegActual = 0;
lError = 0x00;
*cError = 0x00;
rError = ERROR;
}
/**************************************************************************\
| |
| Destructor de clase |
| |
| Descripcion: |
| Finaliza las operaciones pendientes. |
| |
| |
| Entradas: (ninguno) |
| |
| Salidas: (ninguna) |
| |
| |
\**************************************************************************/
BDatos::~BDatos()
{
if ( rError == ERROR ) return;
fclose( handle_BDatos );
}
/**************************************************************************\
| |
| Registros |
| |
| Descripcion: |
| Obtiene el n£mero de registros total de la base de datos. |
| |
| |
| Entradas: (ninguna) |
| |
| Salidas: numero de registros |
| |
\**************************************************************************/
long BDatos::Registros(void)
{
return BDatosHeader.NRegistros;
}
/**************************************************************************\
| |
| NRegTotal |
| |
| Descripcion: |
| Obtiene el n£mero de registros total, total del la base. |
| |
| |
| Entradas: (ninguna) |
| |
| Salidas: numero de registros |
| |
\**************************************************************************/
long BDatos::NRegTotal(void)
{
return BDatosHeader.NRegTotal;
}
/**************************************************************************\
| |
| RegActual |
| |
| Descripcion: |
| Obtiene el n£mero de registro actual. |
| |
| |
| Entradas: (ninguna) |
| |
| Salidas: numero de registro en tratamiento |
| |
\**************************************************************************/
long BDatos::RegActual(void)
{
return NRegActual;
}
/**************************************************************************\
| |
| AbrirReg |
| |
| Descripcion: |
| Abre los ficheros indices y datos. |
| |
| |
| Entradas: nombre fichero "sin comodines" |
| longitud de un registro "en bytes" |
| |
| Salidas: OK ( todo va bien ) |
| ERROR ( error ) |
| |
| |
\**************************************************************************/
int BDatos::AbrirReg(char *file, long sizereg)
{
// char bdatos[ARCH_LEN];
char *bdatos;
BDatosHeader.MyHeader = MyHeader;
Header NewHeader = BDatosHeader;
rError = OK;
bdatos = file;
if ( (handle_BDatos = fopen( bdatos, "r+b" ) ) == NULL )
{
// Inicializamos una nueva base de datos
if ( (handle_BDatos = fopen( bdatos, "w" ) ) == NULL )
{
lError = 0x01; ObtenError( lError );
return (rError = ERROR);
}
rewind( handle_BDatos );
BDatosHeader.SizeReg = sizereg;
BDatosHeader.NRegistros = 0;
BDatosHeader.NRegTotal = 0;
fwrite( &BDatosHeader, sizeof( BDatosHeader ), 1, handle_BDatos );
fclose( handle_BDatos );
if ( (handle_BDatos = fopen( bdatos, "r+b" ) ) == NULL )
{
lError = 0x01; ObtenError( lError );
return (rError = ERROR);
}
} else {
rewind( handle_BDatos );
fread( &BDatosHeader, sizeof(BDatosHeader), 1, handle_BDatos);
if ( BDatosHeader.SizeReg != sizereg || BDatosHeader.VerHi != NewHeader.VerHi )
{
lError = 0x03; ObtenError( lError );
fclose( handle_BDatos );
return (rError = ERROR);
}
}
return OK;
}
/**************************************************************************\
| |
| CerrarReg |
| |
| Descripcion: |
| Cierra la base de datos. |
| |
| |
| Entradas: (ninguno) |
| |
| Salidas: OK ( todo va bien ) |
| ERROR ( error ) |
| |
\**************************************************************************/
void BDatos::CerrarReg( void )
{
if ( rError == ERROR ) return;
fclose( handle_BDatos );
rError = ERROR;
}
/**************************************************************************\
| |
| LeeReg |
| |
| Descripcion: |
| Lee el registro de la posici¢n 'pos' y lo almacena en 'dato' |
| |
| |
| Entradas: puntero a los datos |
| posicion a leer |
| |
| Salidas: OK ( todo va bien ) |
| ERROR ( error ) |
| |
\**************************************************************************/
int BDatos::LeeReg( void *dato, long pos )
{
BTree inx;
if ( rError == ERROR )
{
lError = 0x05; ObtenError( lError );
return ERROR;
}
if ( pos >= BDatosHeader.NRegistros || pos < 0 )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
NRegActual = pos;
fseek( handle_BDatos, (long)( pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
if ( inx.pos < 0 || inx.code != ' ' )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
fseek( handle_BDatos, (long)( inx.pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
fread ( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
return OK;
}
/**************************************************************************\
| |
| EscribeReg |
| |
| Descripcion: |
| Escribe el registro en la posici¢n 'pos' de 'dato' |
| |
| |
| Entradas: puntero a los datos |
| posicion a escribir |
| |
| Salidas: OK ( todo va bien ) |
| ERROR ( error ) |
| |
\**************************************************************************/
int BDatos::EscribeReg( void *dato, long pos )
{
BTree inx;
if ( rError == ERROR )
{
lError = 0x05; ObtenError( lError );
return ERROR;
}
if ( pos > BDatosHeader.NRegistros || pos < 0 )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
NRegActual = pos;
fseek( handle_BDatos, (long)( pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
if ( inx.pos < 0 || inx.code != ' ' )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
fseek( handle_BDatos, (long)( inx.pos * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
fwrite( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
return OK;
}
/**************************************************************************\
| |
| InsReg |
| |
| Descripcion: |
| Inserta un registro, en la posici¢n 'pos' por arriba o abajo |
| |
| |
| Entradas: puntero a los datos a insertar, posici¢n, ARRIBA o ABAJO |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
int BDatos::InsReg( void *dato, long pos, char ab )
{
BTree inx, old_inx;
unsigned long avance;
if ( rError == ERROR )
{
lError = 0x05; ObtenError( lError );
return ERROR;
}
// Filtro los datos conflictivos
if ( pos == 0 && BDatosHeader.NRegistros == 1 && ab == ARRIBA )
{
pos = 1;
} else
if ( pos == (BDatosHeader.NRegistros - 1) && ab == ARRIBA )
{
pos = BDatosHeader.NRegistros;
}
BDatosHeader.NRegistros++;
if ( pos > (BDatosHeader.NRegistros-1) || pos < 0 )
// if ( pos >= (BDatosHeader.NRegistros-1) && BDatosHeader.NRegistros!=1 )
{
BDatosHeader.NRegistros--;
lError = 0x04; ObtenError( lError );
return ERROR;
}
// Si hay fichas eliminadas, utilizamos sus direcciones intermedias.
if ( (BDatosHeader.NRegTotal - ( BDatosHeader.NRegistros - 1 ) ) > 0 )
{
fseek( handle_BDatos, (long)( ( BDatosHeader.NRegistros - 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &old_inx, sizeof( BTree ), 1, handle_BDatos );
} else {
old_inx.pos = ( BDatosHeader.NRegistros - 1 );
BDatosHeader.NRegTotal++;
}
// |<---------- RegTot ----------->|
// |<----- NRegistros ---->| |
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
// ³ 1 ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ * ³ ³ ³ ³ ³ ³
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
//
// 2 up Âpos+1
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
// ³ 1 ³ 2 ³ * ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ ³ ³ ³ ³ ³
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
// 2 down Âpos
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
// ³ 1 ³ * ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ ³ ³ ³ ³ ³
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
avance = ( BDatosHeader.NRegistros - 1 );
while ( avance > ( pos + ab ) )
{
fseek( handle_BDatos, (long)( ( avance - 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
fseek( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fwrite( &inx, sizeof( BTree ), 1, handle_BDatos );
avance--;
};
if ( ( BDatosHeader.NRegistros - 1 ) == 0 )
fseek( handle_BDatos, sizeof( Header ), SEEK_SET);
else {
ab = ( ( BDatosHeader.NRegistros - 1 ) <= ( pos + ab ) ) ? 0 : ab;
fseek( handle_BDatos, (long)( ( pos + ab ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
}
NRegActual = ( BDatosHeader.NRegistros - 1 ) == 0 ? 0 : pos + ab;
old_inx.code = ' ';
fwrite( &old_inx, sizeof( BTree ), 1, handle_BDatos );
fseek( handle_BDatos, (long)( ( old_inx.pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
fwrite( dato, BDatosHeader.SizeReg, 1, handle_BDatos );
rewind( handle_BDatos );
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
return OK;
}
/**************************************************************************\
| |
| DelReg |
| |
| Descripcion: |
| Borra un registro, de la posici¢n 'pos' |
| |
| |
| Entradas: posici¢n a borrar |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
int BDatos::DelReg( long pos )
{
BTree inx, old_inx;
if ( rError == ERROR )
{
lError = 0x05; ObtenError( lError );
return ERROR;
}
BDatosHeader.NRegistros--;
if ( pos > BDatosHeader.NRegistros || pos < 0)
{
BDatosHeader.NRegistros++;
lError = 0x04; ObtenError( lError );
return ERROR;
}
fseek( handle_BDatos, (long)( ( pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &old_inx, sizeof( BTree ), 1, handle_BDatos );
// |<---------- RegTot ----------->|
// |<----- NRegistros ---->| |
// ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
// ³ 1 ³ 2 ³ 5 ³ 6 ³ 4 ³ 3 ³ * ³ * ³ ³ ³ ³ ³ ³
// ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
//
unsigned long avance;
avance = pos;
while ( avance < BDatosHeader.NRegistros )
{
fseek ( handle_BDatos, (long)( ( avance + 1 ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread ( &inx, sizeof( BTree ), 1, handle_BDatos );
fseek ( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fwrite( &inx, sizeof( BTree ), 1, handle_BDatos );
avance++;
};
NRegActual = BDatosHeader.NRegistros == 1 ? 0 : ( BDatosHeader.NRegistros - 1);
fseek( handle_BDatos, (long)( ( BDatosHeader.NRegistros ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
old_inx.code = '*';
fwrite( &old_inx, sizeof( BTree ), 1, handle_BDatos );
rewind( handle_BDatos );
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
return OK;
}
/**************************************************************************\
| |
| ShortReg |
| |
| Descripcion: |
| Corta el fichero y lo hace mas peque¤o. |
| |
| |
| Entradas: (ninguna) |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
int BDatos::ShortReg(void)
{
long avance, recorrido;
BTree inx, curr_inx;
void *SWAPdatos;
char enc;
if ( ( BDatosHeader.NRegTotal - BDatosHeader.NRegistros ) <= 0 ) return OK;
if ( ( SWAPdatos = calloc( 1, BDatosHeader.SizeReg ) ) == NULL )
{
lError = 0x07; ObtenError( lError );
return ERROR;
}
avance = BDatosHeader.NRegTotal-1;
while( avance >= BDatosHeader.NRegistros )
{
// Obtengo la direcci¢n del campo que est  libre y el dato.
fseek( handle_BDatos, (long)( ( avance ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx, sizeof( BTree ), 1, handle_BDatos );
fread( SWAPdatos, BDatosHeader.SizeReg, 1, handle_BDatos );
// Busco la direcci¢n del indice para la ficha actual.
recorrido = avance; enc = FALSO;
while( recorrido >= 0 && !enc )
{
fseek( handle_BDatos, (long)( ( recorrido ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &curr_inx, sizeof( BTree ), 1, handle_BDatos );
if ( curr_inx.pos == avance )
enc = CIERTO;
else
recorrido--;
}
// Si alguien de fuera referencia a esa ficha...
if ( enc )
{
curr_inx.pos = inx.pos;
//Actualizo el indice para comunicarle la nueva posici¢n.
fseek( handle_BDatos, (long)( ( recorrido ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fwrite( &curr_inx, sizeof( BTree ), 1, handle_BDatos );
// Pongo la ficha actual en la direcci¢n libre.
fseek ( handle_BDatos, (long)( ( curr_inx.pos ) * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) + sizeof( BTree ) ), SEEK_SET );
fwrite( SWAPdatos, BDatosHeader.SizeReg, 1, handle_BDatos );
}
avance--;
};
// Actualizo la base de registros
NRegActual = BDatosHeader.NRegistros - 1;
BDatosHeader.NRegTotal = BDatosHeader.NRegistros;
rewind( handle_BDatos );
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
// Corto todo lo que sobra de fichero
if ( chsize( fileno(handle_BDatos), (long)(sizeof( Header ) + ( BDatosHeader.NRegistros * ( sizeof( BTree ) + BDatosHeader.SizeReg ) )) ) == -1 )
{
lError = 0x08; ObtenError( lError );
return OK; // Este error no es del todo grave, pero se avisa.
}
free( SWAPdatos );
return OK;
}
/**************************************************************************\
| |
| ObtenError |
| |
| Descripcion: |
| Obtiene el error correspondiente al codigo dado. |
| |
| |
| Entradas: codigo de error |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
void BDatos::ObtenError( int code )
{
switch( code )
{
case 0x00:
strcpy( cError, "No hay errores" );
break;
case 0x01:
strcpy( cError, "Imposible inicializar base de datos" );
break;
case 0x02:
strcpy( cError, "No se puede abrir el fichero" );
break;
case 0x03:
strcpy( cError, "Version de fich. incompatible" );
break;
case 0x04:
strcpy( cError, "No se pudo acceder a esa posici¢n." );
break;
case 0x05:
strcpy( cError, "No hay base de datos en uso..." );
break;
case 0x06:
strcpy( cError, "Tama¤os de estructuras no coinciden" );
break;
case 0x07:
strcpy( cError, "Memoria insuficiente. Operaci¢n cancelada" );
break;
case 0x08:
strcpy( cError, "Acceso de operacion no permitida." );
break;
}
}
/**************************************************************************\
| |
| SortReg |
| |
| Descripcion: |
| Ordena la base de datos seg£n especifique el usuario en su |
| funci¢n fcmp... |
| |
| Entradas: /**************************************************************\ |
| | fcmp ||
| | ||
| | Descripcion: ||
| | funci¢n de entrada a SortReg, debe ser realizada ||
| | por el usuario y debe ce¤irse a sus par metros.. ||
| | ||
| | Entradas: ptrs. a dos estructuras de usuario. ( ejm. A, B ) ||
| | Salidas: >> 0 si A >> B ||
| | == 0 si A == B ||
| | << 0 si A << B ||
| \************************************************************** |
| |
| |
| |
| |
| Salidas: ERROR se cargan los registros con el codigo de error esp. |
| OK todo ha ido bien |
| |
\**************************************************************************/
int BDatos::SortReg( int (*fcmp)(const void *, const void *) )
{
char dev;
// Pido memoria para mantener dos elementos auxiliares
if (
( A = calloc( 1, BDatosHeader.SizeReg ) ) == NULL ||
( B = calloc( 1, BDatosHeader.SizeReg ) ) == NULL
)
{
lError = 0x07; ObtenError( lError );
return ERROR;
}
dev = SortRegi( fcmp, 0, BDatosHeader.NRegistros-1 );
free(A); free(B);
return dev;
}
int BDatos::SortRegi( int (*fcmp)(const void *, const void *), long izquierda, long derecha )
{
BTree inx1, inx2;
register long i, j;
i = izquierda; j = derecha;
if ( LeeReg( A, (long)(izquierda+derecha)/2 + 1 ) != OK )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
do {
if ( LeeReg( B, i )!= OK )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
while( i < derecha && fcmp( B, A ) < 0 )
{
i++;
if ( LeeReg( B, i ) != OK )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
};
LeeReg( B, j );
while( j > izquierda && fcmp( A, B ) < 0 )
{
j--;
if ( LeeReg( B, j ) != OK )
{
lError = 0x04; ObtenError( lError );
return ERROR;
}
};
if ( i <= j )
{
// Intercambiamos solo los indices sin chequear si son
// accesibles, ( si no lo fueran, se abria abortado )
fseek( handle_BDatos, (long)( i * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx1, sizeof( BTree ), 1, handle_BDatos );
fseek( handle_BDatos, (long)( j * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fread( &inx2, sizeof( BTree ), 1, handle_BDatos );
fseek( handle_BDatos, (long)( j * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fwrite( &inx1, sizeof( BTree ), 1, handle_BDatos );
fseek( handle_BDatos, (long)( i * ( sizeof( BTree ) + BDatosHeader.SizeReg ) + sizeof( Header ) ), SEEK_SET );
fwrite( &inx2, sizeof( BTree ), 1, handle_BDatos );
i++; j--;
}
} while( i <= j );
if ( izquierda < j ) SortRegi( fcmp, izquierda, j );
if ( i < derecha ) SortRegi( fcmp, i, derecha );
return OK;
}
/**************************************************************************\
| |
| SalvaDatosUsuario |
| |
| Descripcion: |
| Salva los 256 bytes concedidos al usuario. |
| |
| |
| Entradas: Puntero a los datos del usuario |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
void BDatos::SalvaDatosUsuario( void * Datos )
{
// Copio los datos de usuario a mi estructura
memcpy( (void *)BDatosHeader.MyHeader.Other, Datos, sizeof(char)*200 );
// Guardo estos datos
rewind( handle_BDatos );
fwrite( &BDatosHeader, sizeof( Header ), 1, handle_BDatos );
}
/**************************************************************************\
| |
| CargaDatosUsuario |
| |
| Descripcion: |
| Carga los datos de usuario, tantos como nos indiquen |
| |
| |
| Entradas: Puntero a los datos del usuario |
| Tama¤o de los datos a cargar |
| |
| Salidas: (ninguna) |
| |
\**************************************************************************/
void BDatos::CargaDatosUsuario( void * Datos, unsigned char size )
{
// Los datos no tienen que ser cargados, ya que esto se produce al
// abrir el archivo
// Copio los datos de usuario a mi estructura
memcpy( Datos, (void *)BDatosHeader.MyHeader.Other, size );
}

BIN
BDATOS/BDATOS.DSK Normal file

Binary file not shown.

BIN
BDATOS/BDATOS.EXE Normal file

Binary file not shown.

147
BDATOS/BDATOS.HH Normal file
View File

@ -0,0 +1,147 @@
/**************************************************************************\
| |
| Clase para el tratamiento de Bases de Datos |
| |
| Jos David Guilln 1996 (c) |
| |
| |
\**************************************************************************/
#if !defined(__BDatos_HH)
#define __BDatos_HH
#include <stdio.h>
#define OK 0
#define ERROR 1
#define NO_ENC -1
#define ARRIBA 1
#define ABAJO 0
#if !defined(__BDatos_CPP)
#ifdef __cplusplus
extern "C" {
#endif
#endif
typedef struct
{
char ProgName[15]; // Estos datos se comprueban al abrir la base
char VerHi, VerLow; // para saber si es la adecuada para su progr.
char Other[200];
} YourHeader;
typedef struct
{
char NBD[13];
char Eof_Code;
char VerHi, VerLow;
YourHeader MyHeader;
long NRegistros;
long NRegTotal;
long SizeReg;
} Header;
class BDatos {
public:
char lError;
char cError[80];
YourHeader MyHeader;
void ObtenError(int code); // Obtiene el error "code"
long Registros(void); // N§ de registros
long NRegTotal(void); // N§ de registros
long RegActual(void); // Reg. Actual
BDatos(); // Constructor de Clase
~BDatos(); // Destructor de Clase
int AbrirReg( char *file, long sizereg ); // Abre el Fichero
void SalvaDatosUsuario( void * Datos ); // Salva los 256 bytes de usuario
// Carga los datos de usuario
void CargaDatosUsuario( void * Datos, unsigned char size );
void CerrarReg( void ); // Cierra el Fich.
int EscribeReg( void *dato, long pos ); // Escribe un Dato
int LeeReg( void *dato, long pos ); // Lee un Dato
int InsReg( void *dato, long pos, char ab ); // Inserta un Reg en pos.
int DelReg( long pos ); // Borra un Reg de pos.
int ShortReg(void); // Corta el fich. y lo hace mas peque¤o
// Ordena la Base
int SortReg( int (*fcmp)(const void *, const void *) );
// Busca un registro en una base ordenada
int BuscReg( long PosIni, int (*fcmp)(const void *, const void *) );
private:
// Funcion auxiliar de ordenaci¢n
int SortRegi( int (*fcmp)(const void *, const void *), long izquierda, long derecha );
FILE *handle_BDatos; // Handle a la Base
Header BDatosHeader;
long NRegActual;
char filename[80];
char rError;
void *A, *B;
};
#if !defined(__BDatos_CPP)
#ifdef __cplusplus
}
#endif
#endif
#endif
/*
1 2 3 4 5 6 7 8 9 0
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ 6 ³ 9 ³ 1 ³ 4 ³ 5 ³ ³ ³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
INS (2_3)
(si existen archivos borrados: " (TotalRecords+1) mark * " coge su posicion )
1 2 3 4 5 6 7 8 9 0
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ 6 ³ 9 ³ 1 ³ 4 ³ 5 ³*X1³*X2³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
ÀÄÄ^ÀÄÄ^ÀÄÄ^ÀÄÄ^ÀÄÄ^ ³
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ X2³ 6 ³ 9 ³ 1 ³ 4 ³ 5 ³*X2³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
(si no existen archivos borrados: coge la posicion de Records + 1 )
1 2 3 4 5 6 7 8 9 0
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ 6 ³ 7 ³ 1 ³ 4 ³ 5 ³ ³ ³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
ÀÄÄ^ÀÄÄ^ÀÄÄ^ÀÄÄ^ÀÄÄ^
ÀÄrecords = 7ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÄÂÄ
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³7+1³ 6 ³ 7 ³ 1 ³ 4 ³ 5 ³ ³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
ÄÁÄ
DEL (3)
1 2 3 4 5 6 7 8 9 0
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ X ³ 6 ³ 9 ³ 1 ³ 4 ³ 5 ³ ³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
³^ÄÄÙ^ÄÄÙ^ÄÄÙ^ÄÄÙ /.\
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 2 ³ 3 ³ 6 ³ 9 ³ 1 ³ 4 ³ 5 ³*X ³ ³ ³ ³ ³ ³
ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ
Á Reg Mark *
*/

BIN
BDATOS/BDATOS.PRJ Normal file

Binary file not shown.

BIN
BDATOS/BDATOS.TFA Normal file

Binary file not shown.

297
BDATOS/PRUEBA.CPP Normal file
View File

@ -0,0 +1,297 @@
/*************************************************************************\
| |
| Programa para probar el buen funcionamiento de la libreria BDatos .(JD) |
| |
| 12.03.96 |
\*************************************************************************/
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "BDatos.hh"
void Altas(void);
void Bajas(void);
void Listar(void);
void Modificar(void);
void MuestraMenu(void);
int Busca( char *nombre );
void Insertar_Especial(void);
void RellenaBase(void);
int fcmp( const void *A, const void *B );
typedef struct
{
char nombre[15];
char apellidos[50];
long DNI;
int Grupo;
} DummyStruct;
DummyStruct dummy;
BDatos DummyBase;
int main(void)
{
int ok = 0;
strcpy( DummyBase.MyHeader.ProgName, "Dummy Prog..." );
DummyBase.MyHeader.VerHi = 1;
DummyBase.MyHeader.VerLow = 0;
if ( DummyBase.AbrirReg( "dummy.fil", sizeof( DummyStruct ) ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
return 1;
}
do
{
MuestraMenu();
switch( getch() )
{
// Altas
case '1':
Altas();
break;
// Bajas
case '2':
Bajas();
break;
// Modificaciones
case '3':
Modificar();
break;
// Listar
case '4':
Listar();
break;
// CortarRegistros
case '5':
DummyBase.ShortReg();
break;
// Altas
case '6':
Insertar_Especial();
break;
// Ordena la base segun nombre
case '7':
DummyBase.SortReg( fcmp );
break;
case '8':
RellenaBase();
break;
// Fin
case '0':
ok = 1;
break;
};
}while( !ok );
DummyBase.CerrarReg();
return 0;
}
void MuestraMenu(void)
{
clrscr();
cprintf(" M E N é P R I N C I P A L \r\n");
cprintf("-------------------------------\r\n");
cprintf(" 1 Altas ³ nReg: %ld \r\n", DummyBase.Registros() );
cprintf(" 2 Bajas ³ nRegT: %ld \r\n", DummyBase.NRegTotal() );
cprintf(" 3 Modificaciones ³ CReg: %ld \r\n", DummyBase.RegActual() );
cprintf(" 4 Listar ³ --- \r\n");
cprintf(" 5 Cortar Fichero ³ _-ù J.D ù-_\r\n");
cprintf(" ³ ù-_ F.V _-ù\r\n");
cprintf(" 0 Salir al DOS ³ --- \r\n");
cprintf(" ³ F R i \r\n");
cprintf(" 6 Ins. Especial ³ u e S \r\n");
cprintf(" 7 Ordenar Campo ³ T N i \r\n");
cprintf(" ³ u O V \r\n");
}
void RellenaBase(void)
{
int ficha;
cprintf("\r\nRellenando base con 800 fichas. Por favor, espere...");
for( ficha=0; ficha<800; ficha++ )
{
sprintf( dummy.nombre, "P%03d", (800-ficha) );
sprintf( dummy.apellidos, "P%03d", ficha );
dummy.DNI = ficha;
dummy.Grupo = ficha;
// Inserta un Reg por arriba de pos.
if ( DummyBase.InsReg( (void *)&dummy, ficha, ARRIBA ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
}
}
void Altas(void)
{
cprintf("\r\nIntroduzca: ( nombre, apellidos, DNI, Grupo ) \r\n");
scanf( "%14s %49s %ld %d", dummy.nombre, dummy.apellidos, &dummy.DNI, &dummy.Grupo );
// Inserta un Reg por arriba de pos.
if ( DummyBase.InsReg( (void *)&dummy, DummyBase.Registros(), ARRIBA ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
}
void Insertar_Especial(void)
{
int PorDonde, Adonde;
cprintf("\r\nIntroduzca: ( nombre, apellidos, DNI, Grupo ) \r\n");
scanf( "%14s %49s %ld %d", dummy.nombre, dummy.apellidos, &dummy.DNI, &dummy.Grupo );
fflush(stdin);
cprintf("\r\nIntroduzca donde y por donde insertar (1==ARRIBA)(0==ABAJO): ");
scanf( "%d %d", &Adonde, &PorDonde );
fflush(stdin);
PorDonde = ( PorDonde == 1 ) ? ARRIBA : ABAJO ;
// Inserta un Reg por arriba de pos.
if ( DummyBase.InsReg( (void *)&dummy, Adonde, PorDonde ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
cprintf("\r\nRegistros aun abiertos, condici¢n metaestable");
}
}
void Bajas(void)
{
char nombTMP[80];
cprintf("\r\nIntroduzca nombre a eliminar: ");
scanf( "%14s", nombTMP );
if ( Busca( nombTMP ) != OK )
{
cprintf( "\r\nFichero no se encuentra en la base" );
getch();
return;
}
if ( DummyBase.LeeReg( (void *)&dummy, DummyBase.RegActual() ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
cprintf( "%14s %40s %5ld %5d\n\r", dummy.nombre, dummy.apellidos, dummy.DNI, dummy.Grupo );
if ( getch() == 32 ) return;
// Borra el registro de la posicion actual
if ( DummyBase.DelReg( DummyBase.RegActual() ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
}
void Modificar(void)
{
char nombTMP[80];
cprintf("\r\nIntroduzca nombre a modificar: ");
scanf( "%14s", nombTMP );
if ( Busca( nombTMP ) != OK )
{
cprintf( "\r\nFichero no se encuentra en la base" );
getch();
return;
}
cprintf("\r\nIntroduzca: ( nombre, apellidos, DNI, Grupo ) \r\n");
scanf( "%14s %49s %ld %d", dummy.nombre, dummy.apellidos, &dummy.DNI, &dummy.Grupo );
// Escribe el Reg en la base
if ( DummyBase.EscribeReg( (void *)&dummy, DummyBase.RegActual() ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
}
void Listar( void )
{
int i;
cprintf( " Nombre Apelidos D.N.I Grupo \n\r" );
cprintf( "------------------------------------------------------------------------------\n\r" );
for( i=0; i<DummyBase.Registros(); i++ )
{
if ( DummyBase.LeeReg( (void *)&dummy, i ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
cprintf( "%14s %40s %5ld %5d\n\r", dummy.nombre, dummy.apellidos, dummy.DNI, dummy.Grupo );
}
getch();
}
int Busca( char *nombre )
{
int i, enc = ERROR;
for( i=0; i<DummyBase.Registros() && enc != OK; i++ )
{
if ( DummyBase.LeeReg( (void *)&dummy, i ) != OK )
{
cprintf("\r\nSe producio un error: %d", DummyBase.lError );
cprintf("\r\n%s\r\n", DummyBase.cError );
DummyBase.CerrarReg();
exit(1);
}
if ( strcmp( dummy.nombre, nombre ) == 0 )
enc = OK;
}
return enc;
}
int fcmp( const void *A, const void *B )
{
return strcmp( ((DummyStruct *)A) -> nombre, ((DummyStruct *)B) -> nombre );
}

2
G/BACKUP.BAT Normal file
View File

@ -0,0 +1,2 @@
pkzip -ex -rp -u \programs.my\c\gif_lib -x*.sym -x*.obj -x*.bak -x*.exe -x*.lib -x*.lst *.*


300
G/BIN/BGI.CPP Normal file
View File

@ -0,0 +1,300 @@
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <alloc.h>
#include <string.h>
#include <io.h>
#include <dos.h>
#include <bios.h>
#include <fcntl.h>
#include "gif_lib.h"
#define ARCHIVO_Abrir 10
#define ARCHIVO_Cerrar 11
#define MEMORIA 50
#define DECODING 60
#define TAMANYO 70
#define DESCRIPCION 80
#define OK 00
typedef unsigned char DacPalette256[256][3];
void setvgapalette256(DacPalette256 *PalBuf);
extern int far _Cdecl Svga256_fdriver[];
int huge DetectVGA256(){ return 2; }
int MuestraGif( char *file, int PosX, int PosY );
extern unsigned int
_stklen = 16384; /* Increase default stack size. */
/******************************************************************************
* Interpret the command line and scan the given GIF file. *
******************************************************************************/
void main(int argc, char **argv)
{
/* Make some variables global, so we could access them faster: */
int GraphDriver, GraphMode;
char Str[80];
struct text_info TextInfo; /* So we can restore starting text mode. */
installuserdriver("Svga256",DetectVGA256);
gettextinfo(&TextInfo); /* Save current mode so we can recover. */
GraphDriver = DETECT;
initgraph(&GraphDriver, &GraphMode, "");
MuestraGif( argv[1], 0, 0 );
while( !kbhit() );
closegraph();
textmode(TextInfo.currmode);
}
/**************************************************************************\
|* *|
|* MuestraGif *|
|* *|
|* Descripcion: *|
|* Dado el nombre del .GIF, y la posici¢n de inicio f¡sica *|
|* decodifica y muestra est en pantalla... *|
|* *|
|* Entradas: *|
|* Nombre de Archivo, Posiciones iniciales X, Y *|
|* Salidas: *|
|* OK *|
|* C¢digos de Errores *|
|* *|
\*************************************************************************/
#define MIN(x, y) ((x) < (y) ? (x) : (y))
int MuestraGif( char *file, int PosX, int PosY )
{
// int k, sum;
int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode,
ColorMapSize;
DacPalette256 Palette256;
int
RecX,
// ImageNum = 0,
// BackGround = 0,
// ForeGround = 1, /* As close to white as possible. */
MaximumScreenHeight,
// DeviceMaxX = 640, DeviceMaxY = 400, /* Physical device dimensions. */
// ScreenWidth = 320, ScreenHeight = 200, /* Gif image screen size. */
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
GifColorType
*ColorMap;
GifRecordType RecordType;
GifByteType *Extension;
GifRowType *ScreenBuffer;
GifFileType *GifFile;
if ((GifFile = DGifOpenFileName( file )) == NULL)
{
return ARCHIVO_Abrir;
}
if ((ScreenBuffer = (GifRowType *)
malloc( sizeof(GifRowType *))) == NULL)
return MEMORIA;
Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
{
free( ScreenBuffer );
return MEMORIA;
}
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
MaximumScreenHeight = GifFile -> SHeight - 1;
/* Scan the content of the GIF file and load the image(s) in: */
do {
for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */
ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
break;
switch (RecordType)
{
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
return DESCRIPCION;
Row = GifFile -> ITop; /* Image Position relative to Screen. */
Col = GifFile -> ILeft;
Width = GifFile -> IWidth;
Height = GifFile -> IHeight;
if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight)
{
free( ScreenBuffer[0] );
free( ScreenBuffer );
return TAMANYO;
}
if (GifFile -> IInterlace)
{
/* Need to perform 4 passes on the images: */
for ( i = 0; i < 4; i++)
for (j = Row + InterlacedOffset[i]; j < Row + Height;
j += InterlacedJumps[i])
{
if (DGifGetLine(GifFile,
&ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][Col],
Width) == GIF_ERROR)
{
free( ScreenBuffer[0] );
free( ScreenBuffer );
return DECODING;
}
/////////////////////////////////////////////////
///Procesa linea obtenida////////////////////////
/////////////////////////////////////////////////
for ( i = 0; i < Width; i ++ )
putpixel( RecX+PosX, j+PosY, ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][RecX] );
/////////////////////////////////////////////////
/////////////////////////////////////////////////
}
}
else {
for (i = 0; i < Height; i++, Row++)
{
if (DGifGetLine(GifFile, &ScreenBuffer[/*MIN(Row, MaximumScreenHeight)*/0][Col],
Width) == GIF_ERROR)
{
MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight);
}
/////////////////////////////////////////////////
///Procesa linea obtenida////////////////////////
/////////////////////////////////////////////////
for ( RecX = 0; RecX < Width; RecX ++ )
putpixel( RecX+PosX, Row+PosY, ScreenBuffer[/*MIN(j, MaximumScreenHeight)*/0][RecX] );
/////////////////////////////////////////////////
/////////////////////////////////////////////////
}
}
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR)
{
free( ScreenBuffer[0] );
free( ScreenBuffer );
return DECODING;
}
while (Extension != NULL)
{
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
{
free( ScreenBuffer[0] );
free( ScreenBuffer );
return DECODING;
}
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be traps by DGifGetRecordType. */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
/* Lets display it - set the global variables required and do it: */
ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
GifFile -> SColorMap);
ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
GifFile -> SBitsPerPixel);
/* Initialize hardware pallete and also select fore/background color. */
/*
Sum = ((int) ColorMap[1].Red) +
((int) ColorMap[1].Green) +
((int) ColorMap[1].Blue);
j = k = Sum;
*/
for (i = 0; i < ColorMapSize; i++)
{
Palette256[i][0] = ColorMap[i].Red >> 2;
Palette256[i][1] = ColorMap[i].Green >> 2;
Palette256[i][2] = ColorMap[i].Blue >> 2;
/*
Sum = ((int) ColorMap[i].Red) +
((int) ColorMap[i].Green) +
((int) ColorMap[i].Blue);
if (i != 0 && Sum > j) // * Dont use color 0. *
{
ForeGround = i;
j = Sum;
}
if (i != 0 && Sum <= k) // * Dont use color 0. *
{
BackGround = i;
k = Sum;
}
*/
}
setvgapalette256( &Palette256 );
/*
ScreenWidth = GifFile -> SWidth;
ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight);
*/
if (DGifCloseFile(GifFile) == GIF_ERROR)
{
free( ScreenBuffer[0] );
free( ScreenBuffer );
// closegraph();
return ARCHIVO_Cerrar;
}
free( ScreenBuffer[0] );
free( ScreenBuffer );
return OK;
}
/* Setvgapalette256 sets the entire 256 color palette */
/* PalBuf contains RGB values for all 256 colors */
/* R,G,B values range from 0 to 63 */
/* Usage: */
/* DacPalette256 dac256; */
/* */
/* setvgapalette256(&dac256); */
void setvgapalette256(DacPalette256 *PalBuf)
{
struct REGPACK reg;
reg.r_ax = 0x1012;
reg.r_bx = 0;
reg.r_cx = 256;
reg.r_es = FP_SEG(PalBuf);
reg.r_dx = FP_OFF(PalBuf);
intr(0x10,&reg);
}

BIN
G/BIN/DISCO.GIF Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

3
G/BIN/DUMMY Normal file
View File

@ -0,0 +1,3 @@
This file ensures the bin directory will be created when unzipped - this
directory is the default for the unix version for exectutables. Remove it
if the destination is not to here.

BIN
G/BIN/GIF.DSK Normal file

Binary file not shown.

BIN
G/BIN/GIF.EXE Normal file

Binary file not shown.

BIN
G/BIN/GIF.PRJ Normal file

Binary file not shown.

207
G/BIN/GIF_LIB.H Normal file
View File

@ -0,0 +1,207 @@
/******************************************************************************
* In order to make life a little bit easier when using the GIF file format, *
* this library was written, and which does all the dirty work... *
* *
* Written by Gershon Elber, Jun. 1989 *
*******************************************************************************
* History: *
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
******************************************************************************/
#ifndef GIF_LIB_H
#define GIF_LIB_H
#define GIF_LIB_VERSION " Version 1.2, "
#define GIF_ERROR 0
#define GIF_OK 1
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char * GifRowType;
typedef unsigned char GifByteType;
#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg)
#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); }
#ifdef SYSV
#define VoidPtr char *
#else
#define VoidPtr void *
#endif /* SYSV */
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
/* Note entries prefixed with S are of Screen information, while entries */
/* prefixed with I are of the current defined Image. */
typedef struct GifFileType {
int SWidth, SHeight, /* Screen dimensions. */
SColorResolution, SBitsPerPixel, /* How many colors can we generate? */
SBackGroundColor, /* I hope you understand this one... */
ILeft, ITop, IWidth, IHeight, /* Current image dimensions. */
IInterlace, /* Sequential/Interlaced lines. */
IBitsPerPixel; /* How many colors this image has? */
GifColorType *SColorMap, *IColorMap; /* NULL if not exists. */
VoidPtr Private; /* The regular user should not mess with this one! */
} GifFileType;
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* DumpScreen2Gif routine constants identify type of window/screen to dump. */
/* Note all values below 1000 are reserved for the IBMPC different display */
/* devices (it has many!) and are compatible with the numbering TC2.0 */
/* (Turbo C 2.0 compiler for IBM PC) gives to these devices. */
typedef enum {
GIF_DUMP_SGI_WINDOW = 1000,
GIF_DUMP_X_WINDOW = 1001
} GifScreenDumpType;
/******************************************************************************
* O.k. here are the routines one can access in order to encode GIF file: *
* (GIF_LIB file EGIF_LIB.C). *
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
GifFileType *EGifOpenFileName(char *GifFileName, int GifTestExistance);
GifFileType *EGifOpenFileHandle(int GifFileHandle);
void EGifSetGifVersion(char *Version);
int EGifPutScreenDesc(GifFileType *GifFile,
int GifWidth, int GifHeight, int GifColorRes, int GifBackGround,
int GifBitsPerPixel, GifColorType *GifColorMap);
int EGifPutImageDesc(GifFileType *GifFile,
int GifLeft, int GifTop, int Width, int GifHeight, int GifInterlace,
int GifBitsPerPixel, GifColorType *GifColorMap);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, char *GifComment);
int EGifPutExtension(GifFileType *GifFile, int GifExtCode, int GifExtLen,
VoidPtr GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile, GifByteType *GifCodeBlock);
int EGifCloseFile(GifFileType *GifFile);
#ifdef __cplusplus
}
#endif
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
#define E_GIF_ERR_WRITE_FAILED 2
#define E_GIF_ERR_HAS_SCRN_DSCR 3
#define E_GIF_ERR_HAS_IMAG_DSCR 4
#define E_GIF_ERR_NO_COLOR_MAP 5
#define E_GIF_ERR_DATA_TOO_BIG 6
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
#define E_GIF_ERR_DISK_IS_FULL 8
#define E_GIF_ERR_CLOSE_FAILED 9
#define E_GIF_ERR_NOT_WRITEABLE 10
/******************************************************************************
* O.k. here are the routines one can access in order to decode GIF file: *
* (GIF_LIB file DGIF_LIB.C). *
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
GifFileType *DGifOpenFileName(char *GifFileName);
GifFileType *DGifOpenFileHandle(int GifFileHandle);
int DGifGetScreenDesc(GifFileType *GifFile);
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
int DGifGetImageDesc(GifFileType *GifFile);
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
int DGifGetComment(GifFileType *GifFile, char *GifComment);
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
GifByteType **GifExtension);
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
GifByteType **GifCodeBlock);
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
int DGifCloseFile(GifFileType *GifFile);
#ifdef __cplusplus
}
#endif
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/******************************************************************************
* O.k. here are the routines from GIF_LIB file QUANTIZE.C. *
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
int QuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize,
GifByteType *RedInput, GifByteType *GreenInput, GifByteType *BlueInput,
GifByteType *OutputBuffer, GifColorType *OutputColorMap);
#ifdef __cplusplus
}
#endif
/******************************************************************************
* O.k. here are the routines from GIF_LIB file QPRINTF.C. *
******************************************************************************/
extern int GifQuitePrint;
#ifdef __cplusplus
extern "C" {
#endif
#ifdef USE_VARARGS
void GifQprintf();
#else
void GifQprintf(char *Format, ...);
#endif /* USE_VARARGS */
/******************************************************************************
* O.k. here are the routines from GIF_LIB file GIF_ERR.C. *
******************************************************************************/
void PrintGifError(void);
int GifLastError(void);
/******************************************************************************
* O.k. here are the routines from GIF_LIB file DEV2GIF.C. *
******************************************************************************/
int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
int ReqGraphMode2,
int ReqGraphMode3);
#ifdef __cplusplus
}
#endif
#endif /* GIF_LIB_H */

BIN
G/BIN/GIF_LIBC.LIB Normal file

Binary file not shown.

BIN
G/BIN/GIF_LIBH.LIB Normal file

Binary file not shown.

BIN
G/BIN/GIF_LIBL.LIB Normal file

Binary file not shown.

BIN
G/BIN/GIF_LIBM.LIB Normal file

Binary file not shown.

BIN
G/BIN/GIF_LIBS.LIB Normal file

Binary file not shown.

BIN
G/BIN/GRAPHBGI.LIB Normal file

Binary file not shown.

106
G/COMPILE.ME Normal file
View File

@ -0,0 +1,106 @@
The gif_lib library and utilities has been successfully compiled on the
following platforms (you will need ansi c compiler for that):
1. IBM-PC, using Turbo C version 2.0/Borland C++ 2.0.
2. Sun 3, with O.S. 3.5 and O.S. 4.0.3, using gcc (gnu c compiler).
3. Sun 4, with O.S. 4.1.1, using gcc (gnu c compiler).
4. HP workstations, running unix BSD4.3, using gcc (gnu c compiler).
5. SGI personal iris (iris4d) running IRIX 4.3, using its cc.
6. IBM R6000 running aix, using xlc (Ansi C compiler).
The first one (IBM-PC) was the main target of this package. The unix version
compiles all the device independent utilities and more (such as gif to rle
conversions, gif2x11 etc.). The IBM-PC compilation and testing is different
from the unix ones, and are described in seperated section below.
Compile and test - IBM PC
-------------------------
O.k. if you have TC/BC you are in good shape (otherwise you are on your own)
and compilation will be simple:
1. Goto to the makefiles in .\lib and .\util (called makefile.tc in both
places) and change the variable CC_LIBS to the exact place you have your
cc libraries. I use to put them in ram disk (disk f:) for fast access.
Make sure this is short variable or otherwise dos will complain about
lines too long (the stupid 128 chars per line), in linkage...
2. Few of the utilities on .\util needs the TC graphic libraries (the gif2xxxx
utilities). You need to create a library named graphbgi.lib that holds all
the BGI drivers and CHR fonts. You do so by a sequence similar to:
a. bgiobj herc (bgiobj.exe is on one of your TC 2.0 diskettes).
b. bgiobj egavga
c. bgiobj cga
d. bgiobj ibm8514
e. bgiobj pc3270
f. bgiobj goth
g. bgiobj litt
h. bgiobj sans
i. bgiobj trip
This will convert all this drivers/fonts into .OBJ files, which can be all
linked to creat the library:
tlib graphbgi.lib +herc.obj +egavga.obj ... +trip.obj, graphbgi.lst
Copy this library to the same directory as specified by CC_LIBS in 1.
3. Decide what directory you want the executables to br copied to and create
it if it is new. Goto .\util and set the DEST variable in the makefile
(makefile.tc) to that directory.
4. Fire the compilation by executing make-ibm.bat
To test most of the utilities reconfigure test-ibm.bat as follows:
1. make sure the new exectuables directory is in your path variable.
2. The default display program is gif2bgi (in this package). If may want
to change its setup. See ./doc/gif2bgi.doc for more.
3. Set the GIF_DIR variable in the batch file to the absolute path of
./pic directory (hold some gif examples).
Run test-ibm.bat. You will want to print gif2bgi.doc in ./doc so you will
know how to use it (at list how to exit...).
Compile and test - UNIX
-----------------------
Compiling are testing under unix is simpler than the IBMPC:
1. If you are to use the unix unzip utility to unpack this library, you
need to use the -d flag to enforce creation of subdirectories. The
following subdirectories are to be created: bin doc lib pic util.
But I guess you are after this if you are reading this file now...
2. You need to convert all files (almost - gif2X11.* has X capitalized), from
MSDOS convension to unix one. This involves converting to lower case, and
stripping off ^Z from end of file and CR from CR/LF end of line.
You can do it manually, However the DOS2UNIX script will do %99 of the job.
It will convert ALL files found in subdirectories of the current working
directory from upper case to lower case, and strip the CR from the CR/LF
end of line used by MSDOS and ^Z from end of file. It does not check if
the file is binary or a text one, and it will DESTROY the gif images in
./pic/*.gif, as it will strip off any CR or ^Z in them. You better move
the ./pic directory to someplace else before invoking DOS2UNIX and move it
back afterwords. Also you will probably need to issue 'chmod +x dos2unix'
to make it executable.
MAKE SURE no other files but from this unpacked library, exists in the
current and sub directories, and execute dos2unix.
3. Go to the ./lib and ./util directories (they should be lower case, after
dos2unix has been executed), and edit the unix makefiles (makefile.unx)
for the following:
a. Set CC to your c compiler name (usually cc but can be gcc - see in the
makefile.unx).
b. Select the right flags to the c compilers. Flags for SGI cc, and gcc are
provided.
4. Fire the compilation using make-unx. This will leave the executables in
./bin.
Test the package by adding ./bin to your path and firing the 'test-unx' script.
This assumes the display is X11, and the environment variable DISPLAY is set
properly - uses gif2X11 as display utility.
Gershon Elber
gershon@cs.utah.edu

22
G/DOC/GENERAL.DOC Normal file
View File

@ -0,0 +1,22 @@
General information - GIF utilities
-----------------------------------
Each of the utilities provided in 'util' directory perform some kind of
filtering, generating new image, or dumping it to a device.
Because they are not fast, a filter will print (in increasing) order the
current input image line number, any time it needs to read the input, and
will print output image line number (in decreasing order) any time it dumps
out. Other utilities, that only read or write, will always print that half
the same way (but in increasing order). This is true only for utilities
that decodes the data. Utilities (like GifPos that only change positions)
that copies the image as block of compressed data, will print nothing for
two reasons: they can not idetify line number, and mainly as they are much
faster.
Some of the utilities requirs memory in the order of the whole screen, while
others read one scan line at a time. Each utility DOC file, has entry called
'Memory Usage' which will be one of: Line (memory required is in the order
of one scan line), Image (order of biggest image in GIF file), or Screen (order
of GIF file screen). In all cases, a byte is allocated per pixel, so image of
320 by 200 pixels will requires ~64k bytes to hold.

88
G/DOC/GIF2BGI.DOC Normal file
View File

@ -0,0 +1,88 @@
Gif2BGI
--------
Program to display images saved as GIF files on IBM PC display devices using
the BGI (Borland) driver interface.
The program has few stages as follows:
1. Reads GIF file header and determines size of it.
2. Dynamically allocate enough memory to hold all the image internally.
One byte per pixel is always allocated, so a little bit more than
width*height (of screen, not image) bytes are required.
3. Reads all the image in. Interlaced images are read correctly in, although
they are displayed sequentially.
4. Display first image using the defaults as set by the command line option.
5. Goes to interactive mode. For full description of the interactive mode
see below
Usage:
------
Gif2BGI [-q] [-d BGI Directory] [-u UserBGIDrv.Mode] [-z ZoomFactor] [-b]
[-h] GifFile
If no GifFile is given, Gif2BGI will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-d BGI Directory] : Where should we look for default drivers (as supplied
by Borland). For example '-d c:/tc/bgi'.
3. [-u UserBGIDrv.Mode] : Specifies user defined BGI driver. If for example
you have a BGI driver for your special vga called MYVGA.BGI and you want
to run it in mode 2 then type '-u c:/tc/bgi/myvga.2'. Note the absolute
path to the driver must be specified. Also note that we use '/' and not
'\' so they would not be treated as options.
4. [-z ZoomFactor] : Sets zoom factor of the image. Zoom factor should be
power of 2 up to 256. Default is 1 (no zoom).
5. [-h] : print one command line help, similar to Usage above.
Interactive mode:
-----------------
Once the image is displayed, the program goes into interactive mode
which recognizes the following commands:
1. C - get Color and Position.
In this sub menu, a cursor appears, and the Color of the pixel the cursor
is on, with its position in GIF file screen are printed. The 4 arrows may
be used (shifted for faster movement) to move the cursor. Any other key will
abort this sub mode.
2. D - Zoom Down by factor of 2 unless current zoom factor is 1.
3. R - Redraw the image.
4. S - print Status of image and program.
5. U - Zoom Up by factor of 2 unless current zoom factor is 256.
6. 4 arrow keys can be used to pan to the desire direction, if the image
overflow to that direction. If, on the other hand, the image fit into the
Hercules device, arrow keys are ignored. The panning steps are 1/2 screen if
not on image end.
7. ' ' - Space bar may be used to abort current image drawing.
8. ESC - Escape key may be used to abort the program.
Notes:
------
As no color quantization is used in this program if a GIF image has more
colors than the BGI driver support, this program will abort.
This driver is optimized for drivers with one byte per pixel (256 colors)
and will run MUCH faster in these cases.
Bugs:
-----
For some reason I could not figure out on my ATI wonder card, int 10h call
10h (AH = AL = 10h) to set the color registers sometimes result with wrong
colors. Direct access of the card registers gives correct results. I dont do
that to make this program portable but if your driver gives wrong colors it
is probably because it is using this bios call. Any one has anything to add?

62
G/DOC/GIF2EPSN.DOC Normal file
View File

@ -0,0 +1,62 @@
Gif2Epsn
--------
Program to dump images saved as GIF files on Epson type printers.
Usage:
------
Usage: Gif2Epsn [-q] [-d DitherSize] [-t BWThreshold] [-m Mapping] [-i] [-n]
[-p PrinterName] [-h] GifFile
If no GifFile is given, Gif2Epsn will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-d DitherSize] : Sets size of dithering matrix, where DitherSize can be
2,3 or 4 only (for 2x2, 3x3 and 4x4 dithering matrices). Default is 2.
Note image will be displayed in this mode only if Mapping (see -m)
selected this mode.
3. [-t BWThreshold] : Sets threshold level for B&W mapping in percent.
This threshold level is used in the different mappings as selected via -m.
Default is 19%.
4. [-m mapping] : Select method to map colors to B&W. Mapping can be:
0 : Every none background color is considered foreground (white color but
is drawn as black by printer, unless -i is specified).
1 : 0.3 * RED + 0.59 * GREEN + 0.11 * YELLOW > BWThreshold is considered
white color.
2 : Colors are mapped as in 1, and use dithering of size as defined using
-d option. BWthreshold is used here as scaler.
Default is option 0.
5. [-i] : Invert the image, i.e. black -> white, white -> black.
6. [-n] : Nicer image. Uses double density feature of Epson printer, to make
nicer result. This takes more time (and kill your ink cartridge
faster...) but results are usually better.
7. [-p PrinterName] : by default output is sent to LPT1:. If other device
or disk file is required, they should be specified here. Note
devices are NOT specifed with colon, so to use LPT2: instead:
'-p lpt2' is required. Nothing is sent to stdout. If a disk file is
created: '-p file1.eps' then it can be printed any time by the
copy command: 'copy file1.eps prn:/b'. Note the /b for binary copy.
8. [-h] : print one command line help, similar to Usage above.
Notes:
------
The output has aspect ratio of 1, so square image, will be square in its
hardcopy as well.
The widest image can be printed is 640 pixels, on 8 inches paper. You
probably will need to flip wider images, if height is less than that:
'gifflip -r x29.gif | gif2epsn'. Wider images will be clipped.
This utility dumps output to a file/printer directly. I guess it will have
only a limited usage on unix system...

82
G/DOC/GIF2HERC.DOC Normal file
View File

@ -0,0 +1,82 @@
Gif2Herc
--------
Program to display images saved as GIF files on IBM PC Hercules graphic card.
The program has few stages as follows:
1. Reads GIF file header and determines size of it.
2. Dynamically allocate enough memory to hold all the image internally.
One byte per pixel is always allocated, so a little bit more than
width*height (of screen, not image) bytes are required.
3. Reads all the image in. Interlaced images are read correctly in, although
they are displayed sequentially.
4. Display first image using the defaults as set by the command line option.
5. Goes to interactive mode. For full description of the interactive mode
see below
Usage:
------
Gif2Herc [-q] [-d DitherSize] [-z ZoomFactor] [-t BWThreshold] [-m Mapping]
[-i] [-b] [-h] GifFile
If no GifFile is given, Gif2Herc will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-d DitherSize] : Sets size of dithering matrix, where DitherSize can be
2,3 or 4 only (for 2x2, 3x3 and 4x4 dithering matrices). Default is 2.
Note image will be displayed in this mode only if Mapping (see -m)
selected this mode.
3. [-z ZoomFactor] : Sets zoom factor of the image. Zoom factor should be
power of 2 up to 256. Default is 1 (no zoom).
4. [-t BWThreshold] : Sets threshold level for B&W mapping in percent.
This threshold level is used in the different mappings as selected via -m.
Default is 19%.
5. [-m mapping] : Select method to map colors to B&W. Mapping can be:
0 : Every none background color is considered foreground (white).
1 : 0.3 * RED + 0.59 * GREEN + 0.11 * YELLOW > BWThreshold is considered
white.
2 : Colors are mapped as in 1, and use dithering of size as defined using
-d option. BWthreshold is used here as scaler.
Default is option 0 which is much faster than the other two.
6. [-i] : Invert the image, i.e. black -> white, white -> black.
7. [-b] : Disable beeps. Every time image is complete, or wrong key was
presses, sound is generated. -b disables that.
8. [-h] : print one command line help, similar to Usage above.
Interactive mode:
-----------------
Once the image is displayed, the program goes into interactive mode
which recognizes the following commands:
1. C - get Color and Position.
In this sub menu, a cursor appears, and the Color of the pixel the cursor
is on, with its position in GIF file screen are printed. The 4 arrows may
be used (shifted for faster movement) to move the cursor. Any other key will
abort this sub mode.
2. D - Zoom Down by factor of 2 unless current zoom factor is 1.
3. H - Increase dither matrix size, unless current size is maximum (4), were
size is set to minimum (2).
4. I - Invert the image, i.e. white -> black, black -> white.
5. M - increase Color -> BW mapping method, unless current method is maximum
(2), were method is set to minimum (0).
6. R - Redraw the image.
7. S - print Status of image and program.
8. U - Zoom Up by factor of 2 unless current zoom factor is 256.
9. 4 arrow keys can be used to pan to the desire direction, if the image
overflow to that direction. If, on the other hand, the image fit into the
Hercules device, arrow keys are ignored. The panning steps are 1/2 screen if
not on image end.
9. ' ' - Space bar may be used to abort current image drawing.
10. ESC - Escape key may be used to abort the program.

30
G/DOC/GIF2IRIS.DOC Normal file
View File

@ -0,0 +1,30 @@
Gif2Iris
--------
Program to display images saved as GIF files under SGI NeWs window system.
Usage:
------
Gif2Iris [-q] [-f] [-p PosX PosY] [-f] [-h] GifFile
If no GifFile is given, Gif2Iris will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
4. [-f] : Force Gif2Iris to stay in foreground.
2. [-p PosX PosY] : defines position of image on screen. By default the
program will prompt for position.
5. [-h] : print one command line help, similar to Usage above.

42
G/DOC/GIF2PS.DOC Normal file
View File

@ -0,0 +1,42 @@
Gif2PS
------
Program to print GIF file on later printers supporting Postscript.
Usage:
------
Usage: Gif2PS [-q] [-x] [-y] [-s SizeX SizeY] [-p PosX PosY] [-i]
[-n #Copies] [-h] GifFile
If no GifFile is given, Gif2PS will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-x] : Force image to be horizontal. By default image will be positioned
so it will be the biggest. If -x then image will be scaled to be biggest
possible horizontally.
3. [-y] : Same as -x but vertically.
4. [-s SizeX SizeY] : Force image size to be SizeX by SizeY inches.
If image will exit page dimensions, it will scream and die.
Page dimensions are 8.5 by 11.0 inches but only 7.5 by 9.0 are assumed to
be printable.
5. [-p PosX PosY] : Force image lower left corner to be as PosX PosY.
If image will exit page dimensions, it will scream and die.
6. [-i] : Image will be inverted (Black -> White and vice versa).
Mapping from colors is done by 0.3 * RED + 0.59 * GREEN + 0.11 * BLUE
and sometimes inverting the image will look better.
7. [-n #Copies] : Number of copies to print. 1 by default.
8. [-h] : print one command line help, similar to Usage above.

36
G/DOC/GIF2RGB.DOC Normal file
View File

@ -0,0 +1,36 @@
Gif2RGB
-------
Program to convert images saved as GIF to 24 bits RGB image(s).
Usage:
------
Usage: Gif2RGB [-q] [-1] [-o OutFileName] [-h] GifFile
If no GifFile is given, Gif2RGB will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.2
2. [-1] : Only one file in the format of RGBRGB... triplates (Each of R, G, B
is a byte) is being written. This file size is 3 * Width * Height.
If stdout is used for output, this option is implicitly applied.
The default (if not '-1') is 3 files with the names OutFileName.R,
OutFileName.G, OutFileName.B, each of which is Width * Height bytes.
3. [-o OutFileName] : specifies the name of the out file (see also '-1'
above).
3. [-h] : print one command line help, similar to Usage above.
Notes:
------

33
G/DOC/GIF2RLE.DOC Normal file
View File

@ -0,0 +1,33 @@
Gif2Rle
-------
Program to convert images saved as GIF to RLE (utah raster toolkit) format.
Usage:
------
Usage: Gif2Rle [-q] [-a] [-h] GifFile
If no GifFile is given, Gif2Rle will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-a] : Add alpha channel (see rle document) to the output data file.n
3. [-h] : print one command line help, similar to Usage above.
Notes:
------
This routine must be linked with the rle toolkit library librle.a.
As you want to convert images to RLE format, it is reasonable to assume you
have this library available...

37
G/DOC/GIF2X11.DOC Normal file
View File

@ -0,0 +1,37 @@
Gif2X11
--------
Program to display images saved as GIF files under X window system.
Usage:
------
Gif2X11 [-q] [-p PosX PosY] [-d Display] [-f] [-h] GifFile
If no GifFile is given, Gif2X11 will try to read stdin for GIF file.
Note no support exists for setting this program option through X data base
(i.e .Xdefaults)
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-p PosX PosY] : set the position of image on screen. By default the
program will prompt for position.
3. [-d Display] : what server should be connect to.
4. Force attempt to allocate exact colors. This usually will result with
very wrong image if not enough colors can be allocated as the rest of
them will be approximated to the closest one. By default the list bits
of the colors are stripped until success (in allocation) which looks much
better.
5. [-h] : print one command line help, similar to Usage above.

35
G/DOC/GIFASM.DOC Normal file
View File

@ -0,0 +1,35 @@
GifAsm
------
Program to assemble few GIF files into one, or disassemble single GIF file
with multiple images into single image files.
Usage:
------
Usage: GifAsm [-q] [-a] [-d OutFileName] [-h] GifFile(s)
If no GifFile is given, GifAsm will try to read stdin for GIF file, if
in disassembly mode only (-d).
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-a] : Assemble. This is the default, and the GifFile(s) are assembled to
stdout. Note the screen descriptor (including screen color map) is taken
from the first file, while other screen descriptors are ignored.
As this mode requires at list 2 GIF files as input, no attempt will be
made to read stdin if none specified on command line.
3. [-d OutFileName] : Disassmble GifFile (if specified on command line) or
stdin, into several files of the form OutFileNameXX, where XX are two
decimal digits. Obviously up to 100 files can be generated this way.
Note in this mode nothing is sent to stdout.
4. [-h] : print one command line help, similar to Usage above.

53
G/DOC/GIFBG.DOC Normal file
View File

@ -0,0 +1,53 @@
GifBG
-----
Program to generate Back Ground with optionally gradually changing intensity
in any of the basic 8 directions, as a GIF file.
Usage:
------
Usage: GifBG [-q] [-d Dir] [-l #Lvls] [-c R G B] [-m MinI] [-M MaxI]
[-s W H] [-h]
GifBG reads no input, and will dump the created GIF file to stdout.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-d Dir] : select direction the intensity of the background should increase.
Direction can be one of the 8 principle directions:
"T" - for Top "TR" - for Top Right
"R" - for Right "BR" - for Bottom Right
"B" - for Bottom "BL" - for Bottom Left
"L" - for left "TL" - for Top Left
The compass directions may be use as synonym for the above directions, so
for example "NE" is equal to "TR".
Direction is case insensitive.
Default direction is Top (North).
3. [-l #Lvls] : Number of levels the color is going to be scaled to.
Default is 16.
4. [-c R G B] : The color to use as the primary back ground color to scale.
This color is scaled between the minimum intensity (MinI) and maximum
intensity (MaxI) from one end of the screen to the end as defined by Dir.
see below (-m & -M) for MinI & MaxI. Default is Blue (0, 0, 255).
5. [-m MinI] : Minimum intensity (in percent) to scale color. Default 10%
6. [-M MaxI] : Maximum intensity (in percent) to scale color. Default 100%
7. [-s W H] : Size of image to create. Default 640 by 350.
8. [-h] : print one command line help, similar to Usage above.
Notes:
------
If MinI == MaxI = 100 (%) and #Lvls == 2 then boolean mask image of specified
size will be created - all forground. This can be used as a square mask for
gifcomb utility.


40
G/DOC/GIFCLIP.DOC Normal file
View File

@ -0,0 +1,40 @@
GifClip
-------
Program to clip images in GIF files. Only one image in GIF file can be modified
at a time. Neither image relative position to screen, nor screen sizes are
modified (use GifPos for that).
Usage:
------
Usage: GifClip [-q] [-i Xmin Ymin Xmax Ymax] [-n n Xmin Ymin Xmax Ymax] [-h]
GifFile
If no GifFile is given, GifClip will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-i Xmin Ymin Xmax Ymax] : Clip first image to the dimensions as specified
by the 4 coordinates (Xmin Ymin Xmax Ymax) of a box clipping region.
For example: '-i 11 22 33 44' will crop the box from top left [11,22]
to bottom right [33,44] out of the first image.
If the first parameter is bigger than third one (Xmin > Xmax) - they are
swapped. Same for Y.
Dimensions of cropped image must be confined to original image width and
height. Note the clipped image include both min & max boundry, and image
of width W can have coordinates 0 to W-1 (zero based).
Only one of -i or -n can be specified.
3. [-n n Xmin Ymin Xmax Ymax] : same as -i above but for the nth image:
'-n 1 11 22 33 44' is exactly the same as the example in -i. Only one of
-i or -n can be specified.
4. [-h] : print one command line help, similar to Usage above.

38
G/DOC/GIFCLRMP.DOC Normal file
View File

@ -0,0 +1,38 @@
GifCrlMp
--------
Program to modify GIF image colormaps. Any specific image in GIF file can
be modified at a time, or the global screen one.
Usage:
------
Usage: GifClrMp [-q] [-s] [-l ColorMapFile] [-g Gamma] [-i Image#] [-h]
GifFile
If no GifFile is given, GifClip will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-s] : Select the global screen color map.
3. [-l ColorMapFile] : load color map from this file instead of select color
map.
4. [-g Gamma] : Apply gamma correction to selected color map.
5. [-i Image#] : Select the i image color map.
6. [-h] : print one command line help, similar to Usage above.
Notes
-----
1. Default operation is to dump out the selected color map in text format.
2. The file to load/dump is simply one color map entry per line. Each such
entry line has four integers: "ColorIndex Red Green Blue", where color
index is in ascending order starting from 1.

34
G/DOC/GIFCOMB.DOC Normal file
View File

@ -0,0 +1,34 @@
GifComb
-------
Program to combine 2 GIF images of exactly same size, into one. The color maps
are merged and the result should not exceed 256 colors. A boolean mask GIF
file can be used to set which pixel from two images to use each location.
Otherwise any background color from first image is converted to second image
color at that point. Only first image of each file is combined, which again
all file first images must be of exactly the same size.
Usage:
------
Usage: GifComb [-q] [-m MaskGIFFile] [-h] GifFiles
Two GIF files must be specified although the mask GIF file is optional.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-m MaskGIFFile] : the MaskGIFfile can be regular GIF file whose first
image has same dimensions as the combined images. Any non background color
in it will select Image 1 Pixel to output, otherwise Image2 pixel will be
selected. Usually this image will be boolean (two colors only) but does
not have to be!
3. [-h] : print one command line help, similar to Usage above.

26
G/DOC/GIFFIX.DOC Normal file
View File

@ -0,0 +1,26 @@
GifFix
------
Program to attempt and fix broken GIF images.
Currently will "fix" images terminated prematurely by filling the rest of
the image with the darkest color found in image.
Usage:
------
Usage: GifFix [-q] [-h] GifFile
If no GifFile is given, GifFix will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-h] : print one command line help, similar to Usage above.

32
G/DOC/GIFFLIP.DOC Normal file
View File

@ -0,0 +1,32 @@
GifFlip
-------
Program to flip (mirror) GIF file along X or Y axes, or rotate the GIF
file 90 degrees to the left or to the right
Usage:
------
Usage: GifFlip [-q] [-r] [-l] [-x] [-y] [-h] GifFile
If no GifFile is given, GifFlip will try to read stdin for GIF file.
Memory required:
----------------
Image.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-r] : Rotate the GIF file to the right.
3. [-l] : Rotate the GIF file to the left.
4. [-x] : mirror the GIF file along X axis. Very useful if GIF file was
created from another format in with the first line in at image bottom.
Effectively flips first row with last.
5. [-y] : mirror the GIF file along Y axis.
Effectively flips first column with last.
6. [-h] : print one command line help, similar to Usage above.

43
G/DOC/GIFHISTO.DOC Normal file
View File

@ -0,0 +1,43 @@
GifHisto
--------
Program to create histogram of number of pixels using each color. Output
can be formated into a GIF histogram file, or text file - both goes to
stdout.
Usage:
------
Usage: GifHisto [-q] [-t] [-s Width Height] [-n ImageNumber] [-b] [-h] GifFile
If no GifFile is given, GifHisto will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-t] : Force output to be text file of the form: Size of colormap lines
each contains two integers: number of times color appeared, and color
index. This in increasing color index order. This output can be fed
directly to msdos SORT program if number of times color appears ordering
is desired.
The colrmap picked is the one to be used for the image to generate
histogram for, as defined in GIF format.
3. [-s Width Height] : Size of GIF histogram file. The Height of the
histogram should be power of 2 dividable by number of colors in colormap.
Width sets the resolution (accuracy if you like) of the histogram as
the maximum histogram bar is scaled to fit it.
4. [-n ImageNumber] : Image number to test. Default is one.
5. [-b] : Zeros the background color count. As only linear scale bars is
supported and usually the background appears much more times then rest
of colors, deleting back ground count will improve the scaling of other
colors.
6. [-h] : print one command line help, similar to Usage above.

28
G/DOC/GIFINTER.DOC Normal file
View File

@ -0,0 +1,28 @@
GifInter
--------
Program to convert between interlaced and non interlaced images in GIF file.
Usage:
------
Usage: GifInter [-q] [-i] [-s] [-h] GifFile
If no GifFile is given, GifInter will try to read stdin for GIF file.
Memory required:
----------------
Image.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-i] : Force all images in GIF file be interlaced.
3. [-s] : Force all images in GIF file be sequencial (default).
4. [-h] : print one command line help, similar to Usage above.

32
G/DOC/GIFINTO.DOC Normal file
View File

@ -0,0 +1,32 @@
GifInto
-------
Program to save stdin into a file with given name, iff the result file has
size bigger than specified (see below). This can be used to save result in
same files name we started a chain of pipes.
Usage:
------
Usage: GifInto [-q] [-s MinFileSize] [-h] GifFile
GifInto always read from stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-s MinFileSize] : If file is less than MinFileSize, it is deleted and
not renamed to given name. This will prevent from killing the file we
start with along the pipe, if result is empty file, or none complete.
The default for file size is 14 bytes which is 1 bigger than GIF file
stamp (6 bytes) and GIF file screen descriptor (7 bytes), so GIF file with
only GIF stamp and screen descriptor will not be renamed.
3. [-h] : print one command line help, similar to Usage above.

33
G/DOC/GIFPOS.DOC Normal file
View File

@ -0,0 +1,33 @@
GifPos
------
Program to change GIF screen size and reposition images. No test is made to
make sure changes will generate valid GIF files (i.e. images are still
confined to screen etc.)
Usage:
------
Usage: GifPos [-q] [-s Width Height] [-i Left Top] [-n n Left Top] [-h] GifFile
If no GifFile is given, GifPos will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-s Width Height] : set the new screen dimensions, so for example
'-s 1000 800' will set screen to width of 1000 and height of 800.
3. [-i Left Top] : set image relative to screen position, so for example
'-i 100 80' will set image left position to 100 and top position to 80.
This sets the position of the first image only.
4. [-n n Left Top] : set image n relative to screen position, so for
example '-n 3 100 80' will set the third image position as in 2.
5. [-h] : print one command line help, similar to Usage above.

40
G/DOC/GIFROTAT.DOC Normal file
View File

@ -0,0 +1,40 @@
GifRotat
--------
Program to rotate a gif image by an arbitrary angle.
Usage:
------
Usage: GifRotat -a Angle [-q] [-s Width Height] [-h] GifFile
If no GifFile is given, GifRotat will try to read stdin for GIF file.
Memory required:
----------------
Screen (of source image).
Options:
--------
1. -a Angle : Specifies the angle to rotate in degrees with respect to
the X (horizontal) axis.
2. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.2
3. [-s Width Height] : Since rotated image will have the same image size as
original, some parts of the image will by clipped out and lost. By
specifing a (bigger) size explicitly using the '-s' option, these parts
may be saved.
3. [-h] : print one command line help, similar to Usage above.
Notes:
------
Image is rotated around its center. No filtering is performed on the output
which have identical color map as the input. This is mainly since filtering
will require color quantization which is very memory/time intensive and
out of MSDOS memory limits even for small images.

33
G/DOC/GIFRSIZE.DOC Normal file
View File

@ -0,0 +1,33 @@
GifRSize
--------
Program to resize image size by integer factor, using bits deleting (scaling
down) and bits duplication (scaling up).
Usage:
------
Usage: GifRSize [-q] [-S X Y] [-s Scale] [-x XScale] [-y YScale] [-h] GifFile
If no GifFile is given, GifRSize will try to read stdin for GIF file.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-S X Y] : specifies the exact screen dimension of the output GIF.
2. [-s Scale] : Set scaling factor for both x & y direction to Scale.
Default is 0.5. Note this is a floating point number.
3. [-x XScale] : Set scaling factor for x direction to Scale. Default is 0.5.
Note this is a floating point number.
4. [-y YScale] : Set scaling factor for y direction to Scale. Default is 0.5.
Note this is a floating point number.
7. [-h] : print one command line help, similar to Usage above.

41
G/DOC/GIFTEXT.DOC Normal file
View File

@ -0,0 +1,41 @@
GifText
-------
Program to print (text only) general information about GIF file
Usage:
------
Usage: GifText [-q] [-c] [-e] [-z] [-p] [-r] [-h] GifFile
If no GifFile is given, GifText will try to read stdin for GIF file.
As giftext can generate huge amount of data, ^C will kill it, but 'q' will
stop only the printing (of one of -e, -z, -p), while file integrity will still
be checked.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-c] : Dumps also color maps.
3. [-e] : Dumps also encoded bytes - the pixels after compressed using LZ
algorithm and chained to form bytes. This is the form the data is saved
in the GIF file. Dumps in hex - 2 digit per byte.
4. [-z] : Dumps also the LZ codes of the image. Dumps in hex - 3 digits per
code (as we are limited to 12 bits).
5. [-p] : Dumps aslo the pixels of the image. Dumps in hex - 2 digit per
pixel (<=byte).
6. [-r] : Dumps raw pixels as one byte per pixel. This option inhibit all other
options and only the pixels are dumped. This option may be used to convert
gif file into raw data. Note the color map can be extracted by gifclrmp
utility. If more than one image exists, all images will be dumped in order.
7. [-h] : print one command line help, similar to Usage above.

32
G/DOC/GIFWEDGE.DOC Normal file
View File

@ -0,0 +1,32 @@
GifWedge
--------
Program to create a test GIF image with intensity levels of the RGB colors
YCM colors and white.
Usage:
------
Usage: GifWedge [-q] [-l #Lvls] [-s SizeX SizeY] [-h]
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-l #Lvls] : Set number of intensity levels per color. This number must be
power of two up to 32 as Gif format can only have 256 color simultanuously
and 7 basic colors are to be displayed.
3. [-s SizeX SizeY] : Force image size to be SizeX by SizeY pixels.
Image size will be rounded down to be a multiple of number of intensities
horizontally, and 7 (colors) vertically.
4. [-h] : print one command line help, similar to Usage above.

477
G/DOC/GIF_LIB.DOC Normal file
View File

@ -0,0 +1,477 @@
GIF library document
--------------------
Gershon Elber, May 1991
-----------------------
Version 1.2
-----------
The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe
Incorporated.
This library was written once I didnt find anything similar and I
wanted one. I was inspired from the rle Utah tool kit, which I hoped to port
to an IBM PC, but found it to be too machine specific, and its compression
ratio too low. I compromised on the GIF format while I am not sure how long
8 bits per pixel will be enough.
This document explains the GIF library kernel on directory GIF/LIB.
The kernel is built to the gif_libl.lib which is used in all the utilities
on GIF/UTIL, or can be used in any application needs to read/write GIF file
format. This document does NOT explain the GIF file format and assumes it
is known, at list to the level of the GIF file structure.
When a GIF file is opened, a GIF file descriptor is maintained which
is a pointer to GifFileType structure as follows:
typedef struct GifFileType {
int SWidth, SHeight, /* Screen dimensions */
SColorResolution, SBitsPerPixel; /* How many colors can we generate? */
SBackGroundColor, /* I hope you understand this one... */
ILeft, ITop, IWidth, IHeight, /* Current image dimensions */
IInterlace, /* Sequential/Interlaced lines */
IBitsPerPixel; /* How many colors this image has? */
GifColorType *SColorMap, *IColorMap; /* NULL if not exists */
void *Private; /* The regular user should not mess with this one! */
} GifFileType;
This structure was copied from gif_lib.h - the header file for the GIF
library. Any application program that uses the gif_libl.lib library should
include it. All items begin with S refer to GIF Screen, while the ones with I
to current image (note GIF file may have more than one image). The user NEVER
writes into this structure, but can read any of these items at any time it is
proper (image information is invalid until first image was read/write).
As the library needs to save its own internal data also, a Private
pointer to internal structure is also saved there. Applications should ignore
this item.
The library has no static data. This means that it is fully reentrant
and any number of GIF files (up to memory limits) can be opened for
read/write. Instead of the static data, internal structure pointed by the
Private pointer is used.
The library do allocates its own memory dynamically, on opening of
file, and releases that once closed. The user is NEVER requires to allocate
any memory for any of the functions of this library (unless the provided
parameters, such as image line, were prefered to be allocated dynammically by
the user) nor to free them directly. In order to reduce disk access, the file
buffer is increased to FILE_BUFFER_SIZE (defined in gif_lib.h). The library
was compiled in large model as the memory allocated per file is quite big:
about 17k for decoding (DGIF_LIB.C), and 32k for encoding (EGIF_LIB.C),
excluding the FILE_BUFFER_SIZE.
We now can see what the library contains (directory GIF/LIB):
1. EGIF_LIB.C - Encoding routines, all prefixed with E.
2. DGIF_LIB.C - Decoding routines, all prefixed with D.
3. DEV2GIF.C - Routines to convert specific device buffers into GIF files.
4. GIF_ERR.C - Error handler for the library.
The library has fifth hashing table file in which is accessed internally
only.
Major part of the routines returns ERROR (see gif_lib.h) if something went
wrong or OK otherwise. Once ERROR received, GIF_ERR.C module can be used to
do something about it.
In addition a module to scan the command line arguments was added.
This module is called GETARG.C and its headers are in GETARG.H. see header
of GETARG.C for details on its usage.
ENCODING (EGIF_LIB.C)
---------------------
GifFileType *EGifOpenFileName(char *GifFileName, int GifTestExistance);
Open a new GIF file using the given GifFileName. If GifTestExistance
is TRUE, and file exists, the file is not destroyed, and NULL returned.
If any error occurs, NULL is returned and Error handler can be used
to get the exact error (see GIF_ERR.C).
The file is opened in binary mode, and its buffer size is set to
FILE_BUFFER_SIZE bytes.
GifFileType *EGifOpenFileHandle(int GifFileHandle);
Open a new GIF file using the given GifFileHandle
If any error occurs, NULL is returned and Error handler can be used
to get the exact error (see GIF_ERR.C)
The file is opened in binary mode, and its buffer size is set to
FILE_BUFFER_SIZE bytes.
void EGifSetGifVersion(char *Version);
Sets the GIF version of all files to be open from this point (until
another call to this routine is made. Version is a 3 characters
string of the form "87a" or "89a". No test is made to validate this
string.
int EGifPutScreenDesc(GifFileType *GifFile,
int GifWidth, int GifHeight, int GifColorRes, int GifBackGround,
int GifBitsPerPixel, GifColorType *GifColorMap);
Update GifFile Screen parameters, in GifFile structure and in real
file. if error occurs returns ERROR (see gif_lib.h), otherwise OK.
This routine should be called immediately after the GIF file was
opened.
int EGifPutImageDesc(GifFileType *GifFile,
int GifLeft, int GifTop, int Width, int GifHeight, int GifInterlace,
int GifBitsPerPixel, GifColorType *GifColorMap);
Update GifFile Image parameters, in GifFile structure and in real
file. if error occurs returns ERROR (see gif_lib.h), otherwise OK.
This routine should be called each time a new image should be
dumped to the file.
int EGifPutLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen);
Dumps block of pixels out to the GIF file. The line length can be
of any length. More than that, this routine may be interleaved with
EGifPutPixel, until all pixels were sent.
Returns ERROR if something went wrong, OK otherwise.
int EGifPutPixel(GifFileType *GifFile, PixelType GifPixel);
Dumps one pixel to the GIF file. This routine may be interleaved
with EGifPutLine, until all pixels were sent. Because of the overhead
per each call, the usage of this routine is not recommended.
Returns ERROR if something went wrong, OK otherwise.
int EGifPutComment(GifFileType *GifFile, char *GifComment);
Uses extension GIF records to save a string as a comment is the file.
The extension code is 'C' (for Comment). This is optional in GIF file.
Returns ERROR if something went wrong, OK otherwise.
int EGifPutExtension(GifFileType *GifFile, int GifExtCode, int GifExtLen,
void *GifExtension);
Dumps the given extension block into the GIF file. Extension blocks
are optional in GIF file. Extension blocks of more than 255 bytes or
more than one block are not supported.
Returns ERROR if something went wrong, OK otherwise.
int EGifPutCode(GifFileType *GifFile, int *GifCodeSize,
ByteType **GifCodeBlock);
It sometimes may be desired to write the compressed code as is
without decoding it. For example a filter for GIF file that change
only screen size (GifPos), does not need the exact pixel values and
pipes out the compressed image as is, make this process much faster.
This routine do exactly that (with EGifPutCodeNext), and can be
used instead of EGifPutLine. This usually works with the
DGifGetCode/DgifGetCodeNext routines, which reads the compressed
code, while EGifPutCode/EGifPutCodeNext write it out. See GifPos.c
for example.
Returns ERROR if something went wrong, OK otherwise.
int EGifPutCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock);
See EGifPutCode above.
int EGifCloseFile(GifFileType *GifFile);
Close GIF file and free all memory allocated for it. GifFile should
not be used, once this routine was called.
Returns ERROR if something went wrong, OK otherwise.
DECODING (DGIF_LIB.C)
---------------------
GifFileType *DGifOpenFileName(char *GifFileName);
Open a new GIF file using the given GifFileName, and read its Screen
information.
If any error occurs, NULL is returned and Error handler can be used
to get the exact error (see GIF_ERR.C).
The file is opened in binary mode, and its buffer size is set to
FILE_BUFFER_SIZE bytes.
GifFileType *DGifOpenFileHandle(int GifFileHandle);
Open a new GIF file using the given GifFileHandle, and read its
Screen information.
If any error occurs, NULL is returned and Error handler can be used
to get the exact error (see GIF_ERR.C)
The file is opened in binary mode, and its buffer size is set to
FILE_BUFFER_SIZE bytes.
int DGifGetScreenDesc(GifFileType *GifFile);
Reads the screen information into the GifFile structure. Note this
routine is automatically called once a file is opened, and therefore
usually not needed.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
As the GIF file can have different records in arbitrary order, this
routine should be called once the file was open to detect the next
record type, and act upon it. Few types might be returned in GifType:
1. UndefinedRecordType - something is wrong!
2. ScreenDescRecordType - screen information. As the screen information
is automatically read in when the file is open, this usually would
not happen.
3. ImageDescRecordType - next record is Image.
4. ExtensionRecordType - next record is extension block.
5. TerminateRecordType - last record reached, can close the file.
The first Two types can usually be ignored.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetImageDesc(GifFileType *GifFile);
Reads the image information into the GifFile structure.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen);
Load block of pixels from the GIF file. The line length can be
of any length. More than that, this routine may be interleaved with
DGifGetPixel, until all pixels were read.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetPixel(GifFileType *GifFile, PixelType GifPixel);
Loads one pixel from the GIF file. This routine may be interleaved
with DGifGetLine, until all pixels were read. Because of the overhead
per each call, the usage of this routine is not recommended.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetComment(GifFileType *GifFile, char *GifComment);
Load comment from the GIF file. Because DGifGetRecordType will
only tell this records is of type extension, this routine should be
called iff it is known %100 that is must be a comment.
For definition of comment, see EGifPutComment.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
ByteType **GifExtension);
Loads the given extension block from the GIF file. Extension blocks
are optional in GIF file. This routine should be follows by
DGifGetExtensionNext - see below
Returns ERROR if something went wrong, OK otherwise.
int DGifGetExtensionNext(GifFileType *GifFile, ByteType **GifExtension);
As extensions may contain more than one block, use this routine to
continue after DGifGetExtension, until *GifExtension is NULL.
Returns ERROR if something went wrong, OK otherwise.
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
ByteType **GifCodeBlock);
It sometimes may be desired to read the compressed code as is
without decoding it. This routine do exactly that (with
DGifGetCodeNext), and can be used instead of DGifGetLine.
This compressed code information can be written out using the
EGifPutCode/EGifPutCodeNext sequence (see GifPos.c for example).
Returns ERROR if something went wrong, OK otherwise.
int DGifGetCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock);
See DGifGetCode above.
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
This routine can be called instead of DGifGetLine/DGifGetPixel or
DGifGetCode/DGifGetCodeNext to get the 12 bits LZ codes of the images.
It may be used mainly for debugging purposes (see GifText.c for
example).
Returns ERROR if something went wrong, OK otherwise.
int DGifCloseFile(GifFileType *GifFile);
Close GIF file and free all memory allocated for it. GifFile should
not be used, once this routine was called.
Returns ERROR if something went wrong, OK otherwise.
ERROR HANDLING (EGIF_LIB.C)
---------------------------
void PrintGifError(void)
Print one line diagnostic on the last gif_lib error to stderr.
int GifLastError(void)
Return last gif_lib error, and clear the error.
Note it is the user responsibility to call the file closing routine,
so the file will be closed (if was opened), and memory will be released
(if was allocated).
The different error types are defined in gif_lib.h.
DEVICE SPECIFIC (XXX2GIF.C)
---------------------------
int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
int ReqGraphMode2);
Dumps the whole device buffer as specified by GraphDriver and
GraphMode (as defined in TC 2.0 graphics.h) into FileName as GIF file.
Current devices supported:
1. Hercules.
2. EGA, EGA64, EGAMONO (all modes - see TC graphics.h).
3. VGA (all modes - see TC graphics.h).
4. SVGA_SPECIAL. This mode is special and not supported by Borland
graphics.h. ReqGraphDriver must be equal to 999, and ReqGraphMode
is ignored. This modes assumes 800 by 600 in 16 colors.
Returns ERROR if something went wrong, OK otherwise.
5. SGI 4D using gl graphic library - window dump.
6. X11 window dump.
COMMAND LINE PARSING (GETARG.C)
-------------------------------
int GAGetArgs(int argc, char **argv, char *CtrlStr, ...);
Main routine of this module. Given the argc & argv as received by
the main procedure, the command line CtrlStr, and the addresses of
all parameters, parse the command line, and update the parameters.
The CtrlStr defines what types of variables should follow. Look
at the beginning of getarg.c for exact usage.
Returns 0 if successful, error number (as defined by getarg.h)
otherwise.
void GAPrintErrMsg(int Error);
If error occurred in GAGetARgs, this routine may be used to print
one line diagnostic to stderr.
void GAPrintHowTo(char *CtrlStr);
Given same CtrlStr as for GAGetArgs, can be used to print a
one line 'how to use'
Skeleton of GIF filter
----------------------
This completes the functions, application can access. An application
skeleton usually will look like (assuming it is a filter - read GIF file,
modifies it, and write new GIF file) the following example, which only copy
a GIF file from stdin to stdout. Please give a pick to the utilities on the
util directory to get more idea once you fill comfortable with this skeleton.
Also try to follow the coding standards of this package if you want me to
officially add your new utility to it.
#include "getarg.h"
main(... )
{
GifFile *GifFileIn, *GifFileOut;
GAGetArgs( argc, argv, CtrlStr, ... ); /* Process command line */
/* Use the stdin as input (note this also read screen descriptor in: */
if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
QuitGifError(GifFileIn, GifFileOut);
/* Use the stdout as output: */
if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
QuitGifError(GifFileIn, GifFileOut);
/* And dump out its screen information: */
if (EGifPutScreenDesc(GifFileOut,
GifFileIn -> SWidth, GifFileIn -> SHeight,
GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Scan the content of the input GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Put image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn -> ILeft, GifFileIn -> ITop,
GifFileIn -> IWidth, GifFileIn -> IHeight,
GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
GifFileIn -> IColorMap) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Now read image itself in decoded form as we dont really */
/* care what we have there, and this is much faster. */
if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == ERROR ||
EGifPutCode(GifFileOut, CodeSize, CodeBlock) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == ERROR ||
EGifPutCodeNext(GifFileOut, CodeBlock) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* Skip any extension blocks in file: */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
Extension) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* No support to more than one extension blocks, so discard: */
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFileIn, &Extension) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be traps by DGifGetRecordType */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFileIn) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifCloseFile(GifFileOut) == ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
/******************************************************************************
* Close both input and output file (if open), and exit. *
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
PrintGifError();
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
exit(1);
}

125
G/DOC/LIBERROR.DOC Normal file
View File

@ -0,0 +1,125 @@
GIF_LIB ERROR
-------------
Errors as reported from the GIF_LIB library are divided to 2 major parts:
the encoder (errors prefixed by E_GIF_ERR), and the decoder (errors prefixed
by D_GIF_ERR). This document explains them briefly:
Encoding errors:
----------------
1. E_GIF_ERR_OpenFailed
Message printed using PrintGifError: "Failed to open given file"
IO error result when attempt to open the given GIF file.
2. E_GIF_ERR_WriteFailed
Message printed using PrintGifError: "Failed to Write to given file"
IO error result when attempt to write to the given GIF file.
3. E_GIF_ERR_HasScrnDscr
Message printed using PrintGifError: "Screen Descriptor already been set"
Attempt to write second screen descriptor to same GIF file. GIF file should
have exactly one screen descriptor which should be set directly after the
file is opened.
4. E_GIF_ERR_HasImagDscr
Message printed using PrintGifError: "Image Descriptor is still active"
Image descriptor should be sent before and image dump, and no second
image descriptor should be sent before current image dump ended. This error
occured probably because current image was not complete.
5. E_GIF_ERR_NoColorMap
Message printed using PrintGifError: "Neither Global Nor Local color map"
An image must have either global (screen) or local (image) color map.
Neither were given in this case.
6. E_GIF_ERR_DataTooBig
Message printed using PrintGifError: "#Pixels bigger than Width * Height"
The number of pixels dumped for this image is bigger than specified by
image Height times image Width.
7. E_GIF_ERR_NotEnoughMem
Message printed using PrintGifError: "Fail to allocate required memory"
Once an attemp is made to open GIF file, special structures are allocated
to hold internal data for it. If allocation fails this error is returned.
8. E_GIF_ERR_DiskIsFull
Message printed using PrintGifError: "Write failed (disk full?)"
Writing encoded data failed.
9. E_GIF_ERR_CloseFailed
Message printed using PrintGifError: "Failed to close given file"
Closing file failed.
10. E_GIF_ERR_NotWriteable
Message printed using PrintGifError: "Given file was not opened for write"
GIF files can be opened both for read (DGIF part of library) and write
(EGIF part of library). This error occurs when a file is opened for read
(using DGIF) is given to one of the encoding (EGIF) routines.
Encoding errors:
----------------
1. D_GIF_ERR_OpenFailed
Message printed using PrintGifError: "Failed to open given file"
IO error result when attempt to open the given GIF file.
2. D_GIF_ERR_ReadFailed
Message printed using PrintGifError: "Failed to Read from given file"
IO error result when attempt to write to the given GIF file.
3. D_GIF_ERR_NotGifFile
Message printed using PrintGifError: "Given file is NOT GIF file"
GIF files should have special stamp identifies them as such, If that stamp
is not found, this error is issued.
4. D_GIF_ERR_NoScrnDscr
Message printed using PrintGifError: "No Screen Descriptor detected"
Each GIF file should have screen descriptor in its header. This error will
be generated if no such descriptor was found.
5. D_GIF_ERR_NoImagDscr
Message printed using PrintGifError: "No Image Descriptor detected"
Each image should have image descriptor in its header. This error will
be generated if no such descriptor was found.
6. D_GIF_ERR_NoColorMap
Message printed using PrintGifError: "Neither Global Nor Local color map"
An image must have either global (screen) or local (image) color map.
Neither were given in this case.
7. D_GIF_ERR_WrongRecord
Message printed using PrintGifError: "Wrong record type detected"
Each record in GIF file has special identifier, in its header. If the
record has wrong identifier, this error is generated.
8. D_GIF_ERR_DataTooBig
Message printed using PrintGifError: "#Pixels bigger than Width * Height"
The number of pixels dumped for this image is bigger than specified by
image Height times image Width.
9. D_GIF_ERR_NotEnoughMem
Message printed using PrintGifError: "Fail to allocate required memory"
Once an attemp is made to open GIF file, special structures are allocated
to hold internal data for it. If allocation fails this error is returned.
10. D_GIF_ERR_CloseFailed
Message printed using PrintGifError: "Failed to close given file"
Closing file failed.
11. D_GIF_ERR_NotReadable
Message printed using PrintGifError: "Given file was not opened for read"
GIF files can be opened both for read (DGIF part of library) and write
(EGIF part of library). This error occurs when a file is opened for write
(using EGIF) is given to one of the decoding (DGIF) routines.
12. D_GIF_ERR_ImageDefect
Message printed using PrintGifError: "Image is defective, decoding aborted"
This error is generated, once the decoding failed - probably image is
defect.
13. D_GIF_ERR_EOFTooSoon
Message printed using PrintGifError: "Image EOF detected, before image complete"
This error is generated once EOF code is detected in encoded image before
all the pixels (Width * Height) has be decoded.

36
G/DOC/RAW2GIF.DOC Normal file
View File

@ -0,0 +1,36 @@
Raw2Gif
-------
Program to convert RAW image data into GIF files. Only one image can be
handled. The RAW image file, assumes to hold one pixel color in one byte,
and therefore the file size must be Width times Height as specified by the
-s option below.
Usage:
------
Usage: Raw2Gif [-q] -s Width Height [-p ColorMapFile] [-h] RawFile
If no RawFile is given, Raw2Gif will try to read stdin for RAW data.
Gif File is dumped to stdout.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. -s Width Height : the dimensions of the image MUST be specified in the
command line. The RAW image file size must be exactly Width times Height
bytes (each byte is one pixel color).
3. [-p ColorMapFile] : Color map to load for given RAW image. This file has
4 integers in line (ColorIndex Red Green Blue), and the ColorIndex is
in order starting from 1. See GifClrMp, which can also use/create these
bitmap files. If no color map is specified, uses the EGA 16 color pallete
as default color map.
4. [-h] : print one command line help, similar to Usage above.

39
G/DOC/RGB2GIF.DOC Normal file
View File

@ -0,0 +1,39 @@
RGB2Gif
-------
Program to convert 24 bit images to a GIF image using color quantization.
Usage:
------
Usage: RGB2Gif [-q] [-c #Colors] [-1] -s Width Height [-h] RGBFile
If no RGBFile is given, RGB2Gif will try to read stdin for GIF file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-c #Colors] specifies number of colors to use, in bits per pixels, so
'-c 8' specifies actually 256 colors (maximum and default).
3. [-1] : Only one file in the format of RGBRGB... triplates (Each of R, G, B
is a byte) is read from input. This file size is 3 * Width * Height (see
'-s' below. If stdin is used for input, this option is implicitly applied.
The default (if not '-1') is 3 files with the names RGBFile.R, RGBFile.G,
RGBFile.B, each of which is Width * Height bytes.
4. [-s Width Height] specifies the size of the image to read.
5. [-h] : print one command line help, similar to Usage above.
Notes:
------
Due to 8088 limitation, on MSDOS, maximum image size can not exceed
64k pixels.

36
G/DOC/RLE2GIF.DOC Normal file
View File

@ -0,0 +1,36 @@
Rle2Gif
-------
Program to convert images saved as RLE (utah raster toolkit) to GIF format.
Usage:
------
Usage: Rle2Gif [-q] [-c #Colors] [-h] RleFile
If no RleFile is given, Rle2Gif will try to read stdin for Rle file.
Memory required:
----------------
Screen.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-c #Colors] : Select size of color map in the output Gif file. #Colors
should be given as the based 2 log of number of colors. Default is 8
which is 256 colors, and which is also the maximum.
3. [-h] : print one command line help, similar to Usage above.
Notes:
------
As the RLE format allows full 24 bits per pixel (8 per primmery color)
Colors must be quantized to the number of colors as set by the [-c] option,
above. This process is quite slow. See the quantize.c file in the lib
directory for the reference for this quantization algorithm (median cut).

48
G/DOC/TEXT2GIF.DOC Normal file
View File

@ -0,0 +1,48 @@
Text2Gif
--------
Program to generate gif images out of regular text. Text can be one line
or multi line, and is converted using 8 by 8 fix font.
Usage:
------
Usage: Text2Gif [-q] [-s ClrMapSize] [-f FGClr] [-c R G B] [-t "Text"] [-h]
Text2Gif read stdin if no text is provided in the command line (-t),
and will dump the created GIF file to stdout.
Memory required:
----------------
Line.
Options:
--------
1. [-q] : quite mode. Default off on MSDOS, on on unix. Controls printout
of running scan lines. Use -q- to turn off.
2. [-s ClrMapSize] explicitly defines the size of the color map of the
resulting gif image. Usually the image will be bicolor with fg as color
1, unless [-f] is explicitly given in case the color map size will be
big enough to hold it. However it is sometimes convenient to set the
color map size to certain size while the fg color is small mainly so
this image may be merged with another (images must match color map size).
3. [-f FG] : select foreground index (background is always 0). By default
it is one and therefore the image result is bicolored.
if FG is set to n then color map will be created with 2^k entries where
2^k > n for minimum k, assuming k <= 8. This color map will be all zeros
except this forground index. This option is useful if this text image
should be integrated into other image colormap using their colors.
4. [-c R G B] : The color to use as the foreground color. While by default.
5. [-t "Text"] : in case of one line text, it can be provided on the command
line. Note you must encapsulate the Text within quotes if it has spaces
(The quotes themselves are not part of the text). If no -t option is
provided, stdin is read until end of file.
6. [-h] : print one command line help, similar to Usage above.
Notes:
------
There is a hard bound limit on the number of lines, and it is set to 100.

36
G/DOS2UNIX Normal file
View File

@ -0,0 +1,36 @@
#!/bin/csh -f
#
# Gershon Elber, Feb 90.
#
set upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set locase = "abcdefghijklmnopqrstuvwxyz"
echo
echo +++++ Rename directories:
echo
foreach d (`find . -type d -print`)
set new_d = `echo $d | tr $upcase $locase`
if ( "$d" != "$new_d" ) then
echo $d to $new_d
mv $d $new_d
endif
end
echo
echo +++++ Rename files, strip CR/LF to LF and remove DOS ^Z:
echo
foreach f (`find . -type f -print`)
set new_f = `echo $f | tr $upcase $locase`
echo $f to $new_f
tr -d "\015\032" < $f > $new_f.tmp
rm -r $f
mv $new_f.tmp $new_f
end
#
# Do small fixes manually.
#
(chmod +x dos2unix make-unx test-unx)

BIN
G/GIF/BGI.EXE Normal file

Binary file not shown.

BIN
G/GIF/CHERYL.GIF Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
G/GIF/DISCO.GIF Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
G/GIF/GIF.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIF2BGI.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIF2EPSN.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIF2HERC.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIF2PS.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIF2RGB.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFCLRMP.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFCOMB.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFFIX.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFFLIP.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFHISTO.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFINTER.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFINTO.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFPOS.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFROTAT.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFRSIZE.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFTEXT.EXE Normal file

Binary file not shown.

BIN
G/GIF/GIFWEDGE.EXE Normal file

Binary file not shown.

BIN
G/GIF/HERC2GIF.EXE Normal file

Binary file not shown.

BIN
G/GIF/PORSCHE.GIF Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
G/GIF/RAW2GIF.EXE Normal file

Binary file not shown.

BIN
G/GIF/RGB2GIF.EXE Normal file

Binary file not shown.

BIN
G/GIF/SOLID2.GIF Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
G/GIF/TEXT2GIF.EXE Normal file

Binary file not shown.

512
G/LIB/DEV2GIF.C Normal file
View File

@ -0,0 +1,512 @@
/*****************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 1.1, Jun. 1989 *
******************************************************************************
* Module to dump graphic devices into a GIF file. Current supported devices: *
* 1. EGA, VGA, SVGA (800x600), Hercules on the IBM PC (#define __MSDOS__). *
* 2. SGI 4D Irix using gl library (#define __SGI_GL__). *
* 3. X11 using libX.a (#define __X11__). *
******************************************************************************
* History: *
* 22 Jun 89 - Version 1.0 by Gershon Elber. *
* 12 Aug 90 - Version 1.1 by Gershon Elber (added devices). *
*****************************************************************************/
#ifdef __MSDOS__
#include <dos.h>
#include <alloc.h>
#include <graphics.h>
#endif /* __MSDOS__ */
#ifdef __SGI_GL__
#include <gl/gl.h>
#endif /* __SGI_GL__ */
#ifdef __X11__
#include <X11/Xlib.h>
#endif /* __X11__ */
#include <stdio.h>
#include "gif_lib.h"
#define PROGRAM_NAME "GIF_LIBRARY"
#define SVGA_SPECIAL 999 /* 800 by 600 Super VGA mode. */
static int GraphDriver = -1, /* Device parameters - reasonable values. */
GraphMode = -1,
ScreenColorBits = 1;
static long ScreenXMax = 100,
ScreenYMax = 100;
static unsigned int ScreenBase;
#ifdef SYSV
static char *VersionStr =
"Gif library module,\t\tGershon Elber\n\
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#else
static char *VersionStr =
PROGRAM_NAME
" IBMPC "
GIF_LIB_VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#endif /* SYSV */
#if defined(__SGI_GL__) || defined(__X11__)
GifByteType *GlblGifBuffer = NULL, *GlblGifBufferPtr = NULL;
#endif /* __SGI_GL__ || __X11__ */
#ifdef __SGI_GL__
static int QuantizeRGBBuffer(int Width, int Height, long *RGBBuffer,
GifColorType *ColorMap, GifByteType *GIFBuffer);
#endif /* __SGI_GL__ */
static void GetScanLine(GifPixelType *ScanLine, int Y);
static int HandleGifError(GifFileType *GifFile);
/******************************************************************************
* Dump the given Device, into given File as GIF format: *
* Return 0 on success, -1 if device not supported, or GIF-LIB error number. *
* Device is selected via the ReqGraphDriver. Device mode is selected via *
* ReqGraphMode1/2 as follows: *
* 1. IBM PC Hercules card: HERCMONO (one mode only) in ReqGraphMode1, *
* ReqGraphMode2/3 are ignored. *
* 2. IBM PC EGA card: EGALO/EGAHI in ReqGraphMode1, *
* ReqGraphMode2/3 are ignored. *
* 3. IBM PC EGA64 card: EGA64LO/EGA64HI in ReqGraphMode1, *
* ReqGraphMode2/3 are ignored. *
* 4. IBM PC EGAMONO card: EGAMONOHI (one mode only) in ReqGraphMode1, *
* ReqGraphMode2/3 are ignored. *
* 5. IBM PC VGA card: VGALO/VGAMED/VGAHI in ReqGraphMode1, *
* ReqGraphMode2/3 are ignored. *
* 6. IBM PC SVGA card: ReqGraphMode1/2 are both ignored. Fixed mode (800x600 *
* 16 colors) is assumed. *
* 7. SGI 4D using GL: window id to dump (as returned by winget()) in *
* ReqGraphMode1, ReqGraphMode2/3 are ignored. *
* 8. X11: Window id in ReqGraphMode1, Display id in ReqGraphMode2, Color *
* map id in ReqGraphMode3. *
******************************************************************************/
int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
int ReqGraphMode2,
int ReqGraphMode3)
{
int i, j, k;
GifPixelType *ScanLine;
GifFileType *GifFile;
GifColorType *ColorMap = NULL;
#ifdef __MSDOS__
static GifColorType MonoChromeColorMap[] = {
{ 0, 0, 0 },
{ 255, 255, 255 }
};
/* I have no idea what default EGA64 (4 colors) should be (I guessed...).*/
static GifColorType EGA64ColorMap[] = {
{ 0, 0, 0 }, /* 0. Black */
{ 255, 0, 0 }, /* 1. Red */
{ 0, 255, 0 }, /* 2. Green */
{ 0, 0, 255 }, /* 3. Blue */
};
static GifColorType EGAColorMap[] = {
{ 0, 0, 0 }, /* 0. Black */
{ 0, 0, 170 }, /* 1. Blue */
{ 0, 170, 0 }, /* 2. Green */
{ 0, 170, 170 }, /* 3. Cyan */
{ 170, 0, 0 }, /* 4. Red */
{ 170, 0, 170 }, /* 5. Magenta */
{ 170, 170, 0 }, /* 6. Brown */
{ 170, 170, 170 }, /* 7. LightGray */
{ 85, 85, 85 }, /* 8. DarkGray */
{ 85, 85, 255 }, /* 9. LightBlue */
{ 85, 255, 85 }, /* 10. LightGreen */
{ 85, 255, 255 }, /* 11. LightCyan */
{ 255, 85, 85 }, /* 12. LightRed */
{ 255, 85, 255 }, /* 13. LightMagenta */
{ 255, 255, 85 }, /* 14. Yellow */
{ 255, 255, 255 }, /* 15. White */
};
#endif /* __MSDOS__ */
#if defined(__SGI_GL__) || defined(__X11__)
long *RGBBuffer;
GifColorType ColorMap256[256];
#endif
#ifdef __X11__
XImage *XImg;
unsigned long XPixel;
XColor XColorTable[256]; /* Up to 256 colors in X. */
XWindowAttributes WinAttr;
#endif /* __X11__ */
switch (ReqGraphDriver) { /* Return on non supported screens. */
#ifdef __MSDOS__
case HERCMONO:
ScreenXMax = 720;
ScreenYMax = 350;
ScreenColorBits = 1;
ScreenBase = 0xb000;
ColorMap = MonoChromeColorMap;
break;
case EGA:
switch (ReqGraphMode1) {
case EGALO:
ScreenYMax = 200;
break;
case EGAHI:
ScreenYMax = 350;
break;
default:
return -1;
}
ScreenXMax = 640;
ScreenColorBits = 4;
ScreenBase = 0xa000;
ColorMap = EGAColorMap;
break;
case EGA64:
switch (ReqGraphMode1) {
case EGA64LO:
ScreenYMax = 200;
break;
case EGA64HI:
ScreenYMax = 350;
break;
default:
return -1;
}
ScreenXMax = 640;
ScreenColorBits = 2;
ScreenBase = 0xa000;
ColorMap = EGA64ColorMap;
break;
case EGAMONO:
switch (ReqGraphMode1) {
case EGAMONOHI:
ScreenYMax = 350;
break;
default:
return -1;
}
ScreenXMax = 640;
ScreenColorBits = 1;
ScreenBase = 0xa000;
ColorMap = MonoChromeColorMap;
break;
case VGA:
switch (ReqGraphMode1) {
case VGALO:
ScreenYMax = 200;
break;
case VGAMED:
ScreenYMax = 350;
break;
case VGAHI:
ScreenYMax = 480;
break;
default:
return -1;
}
ScreenXMax = 640;
ScreenColorBits = 4;
ScreenBase = 0xa000;
ColorMap = EGAColorMap;
break;
case SVGA_SPECIAL:
ScreenXMax = 800;
ScreenYMax = 600;
ScreenColorBits = 4;
ScreenBase = 0xa000;
ColorMap = EGAColorMap;
break;
#endif /* __MSDOS__ */
#ifdef __SGI_GL__
case GIF_DUMP_SGI_WINDOW:
winset(ReqGraphMode1); /* Select window as active window. */
getsize(&ScreenXMax, &ScreenYMax);
RGBBuffer = (long *) malloc(sizeof(long) * ScreenXMax * ScreenYMax);
readsource(SRC_FRONT);
if (lrectread((short) 0,
(short) 0,
(short) (ScreenXMax - 1),
(short) (ScreenYMax - 1), RGBBuffer) !=
ScreenXMax * ScreenYMax) { /* Get data. */
free(RGBBuffer);
return -1;
}
GlblGifBuffer = (GifByteType *) malloc(sizeof(GifByteType) *
ScreenXMax * ScreenYMax);
i = QuantizeRGBBuffer(ScreenXMax, ScreenYMax, RGBBuffer,
ColorMap256, GlblGifBuffer);
/* Find minimum color map size to hold all quantized colors. */
for (ScreenColorBits = 1;
(1 << ScreenColorBits) < i && ScreenColorBits < 8;
ScreenColorBits++);
/* Start to dump with top line as GIF expects it. */
GlblGifBufferPtr = GlblGifBuffer + ScreenXMax * (ScreenYMax - 1);
ColorMap = ColorMap256;
free(RGBBuffer);
break;
#endif /* __SGI_GL__ */
#ifdef __X11__
case GIF_DUMP_X_WINDOW:
XGetWindowAttributes((Display *) ReqGraphMode2,
(Window) ReqGraphMode1,
&WinAttr);
ScreenXMax = WinAttr.width;
ScreenYMax = WinAttr.height;
XImg = XGetImage((Display *) ReqGraphMode2,
(Window) ReqGraphMode1,
0, 0, ScreenXMax - 1, ScreenYMax - 1,
AllPlanes, XYPixmap);
GlblGifBuffer = (GifByteType *) malloc(sizeof(GifByteType) *
ScreenXMax * ScreenYMax);
/* Scan the image for all different colors exists. */
for (i = 0; i < 256; i++) XColorTable[i].pixel = 0;
k = FALSE;
for (i = 0; i < ScreenXMax; i++)
for (j = 0; j < ScreenYMax; j++) {
XPixel = XGetPixel(XImg, i, j);
if (XPixel > 255) {
if (!k) {
/* Make sure we state it once only.*/
fprintf(stderr, "X Color table - truncated.\n");
k = TRUE;
}
XPixel = 255;
}
XColorTable[XPixel].pixel = XPixel;
}
/* Find the RGB representation of the colors. */
XQueryColors((Display *) ReqGraphMode2,
(Colormap) ReqGraphMode3,
XColorTable,
256);
/* Count number of active colors (Note color 0 is always in) */
/* and create the Gif color map from it. */
ColorMap = ColorMap256;
ColorMap[0].Red = ColorMap[0].Green = ColorMap[0].Blue = 0;
for (i = j = 1; i < 256; i++)
if (XColorTable[i].pixel) {
ColorMap[j].Red = XColorTable[i].red / 256;
ColorMap[j].Green = XColorTable[i].green / 256;
ColorMap[j].Blue = XColorTable[i].blue / 256;
/* Save the X color index into the Gif table: */
XColorTable[i].pixel = j++;
}
/* and set the number of colors in the Gif color map. */
for (ScreenColorBits = 1;
(1 << ScreenColorBits) < j && ScreenColorBits < 8;
ScreenColorBits++);
/* Prepare the Gif image buffer as indices into the Gif color */
/* map from the X image. */
GlblGifBufferPtr = GlblGifBuffer;
for (i = 0; i < ScreenXMax; i++)
for (j = 0; j < ScreenYMax; j++)
*GlblGifBufferPtr++ =
XColorTable[XGetPixel(XImg, j, i) & 0xff].pixel;
XDestroyImage(XImg);
GlblGifBufferPtr = GlblGifBuffer;
ColorMap = ColorMap256;
break;
#endif /* __X11__ */
default:
return -1;
}
ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ScreenXMax);
GraphDriver = ReqGraphDriver;
GraphMode = ReqGraphMode1;
if ((GifFile = EGifOpenFileName(FileName, FALSE)) == NULL ||
EGifPutScreenDesc(GifFile, ScreenXMax, ScreenYMax, ScreenColorBits,
0, ScreenColorBits, ColorMap) == GIF_ERROR ||
EGifPutImageDesc(GifFile, 0, 0, ScreenXMax, ScreenYMax, FALSE, 1,
NULL) == GIF_ERROR) {
free((char *) ScanLine);
#if defined(__SGI_GL__) || defined(__X11__)
free((char *) GlblGifBuffer);
#endif
return HandleGifError(GifFile);
}
for (i = 0; i < ScreenYMax; i++) {
GetScanLine(ScanLine, i);
if (EGifPutLine(GifFile, ScanLine, ScreenXMax) == GIF_ERROR) {
free((char *) ScanLine);
#if defined(__SGI_GL__) || defined(__X11__)
free((char *) GlblGifBuffer);
#endif
return HandleGifError(GifFile);
}
}
if (EGifCloseFile(GifFile) == GIF_ERROR) {
free((char *) ScanLine);
#if defined(__SGI_GL__) || defined(__X11__)
free((char *) GlblGifBuffer);
#endif
return HandleGifError(GifFile);
}
free((char *) ScanLine);
#if defined(__SGI_GL__) || defined(__X11__)
free((char *) GlblGifBuffer);
#endif
return 0;
}
#ifdef __SGI_GL__
/******************************************************************************
* Quantize the given 24 bit (8 per RGB) into 256 colors. *
******************************************************************************/
static int QuantizeRGBBuffer(int Width, int Height, long *RGBBuffer,
GifColorType *ColorMap, GifByteType *GIFBuffer)
{
int i;
GifByteType *RedInput, *GreenInput, *BlueInput;
/* Convert the RGB Buffer into 3 seperated buffers: */
RedInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height);
GreenInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height);
BlueInput = (GifByteType *) malloc(sizeof(GifByteType) * Width * Height);
for (i = 0; i < Width * Height; i++) {
RedInput[i] = RGBBuffer[i] & 0xff;
GreenInput[i] = (RGBBuffer[i] >> 8) & 0xff;
BlueInput[i] = (RGBBuffer[i] >> 16) & 0xff;
}
for (i = 0; i < 256; i++)
ColorMap[i].Red = ColorMap[i].Green = ColorMap[i].Blue = 0;
i = 256;
QuantizeBuffer(Width, Height, &i,
RedInput, GreenInput, BlueInput,
GIFBuffer, ColorMap);
free(RedInput);
free(GreenInput);
free(BlueInput);
return i; /* Real number of colors in color table. */
}
#endif /* __SGI_GL__ */
/******************************************************************************
* Update the given scan line buffer with the pixel levels of the Y line. *
* This routine is device specific, so make sure you know was you are doing *
******************************************************************************/
static void GetScanLine(GifPixelType *ScanLine, int Y)
{
unsigned char ScreenByte;
int i, j, k;
unsigned int BufferOffset, Bit;
#ifdef __MSDOS__
union REGS InRegs, OutRegs;
#endif /* __MSDOS__ */
switch (GraphDriver) {
#ifdef __MSDOS__
case HERCMONO:
BufferOffset = 0x2000 * (Y % 4) + (Y / 4) * (ScreenXMax / 8);
/* In one scan lines we have ScreenXMax / 8 bytes: */
for (i = 0, k = 0; i < ScreenXMax / 8; i++) {
ScreenByte = (unsigned char) peekb(ScreenBase, BufferOffset++);
for (j = 0, Bit = 0x80; j < 8; j++) {
ScanLine[k++] = (ScreenByte & Bit ? 1 : 0);
Bit >>= 1;
}
}
break;
case EGA:
case EGA64:
case EGAMONO:
case VGA:
case SVGA_SPECIAL:
InRegs.x.dx = Y;
InRegs.h.bh = 0;
InRegs.h.ah = 0x0d; /* BIOS Read dot. */
for (i = 0; i < ScreenXMax; i++) {
InRegs.x.cx = i;
int86(0x10, &InRegs, &OutRegs);
ScanLine[i] = OutRegs.h.al;
}
/* Makr this line as done by putting a xored dot on the left. */
InRegs.x.dx = Y;
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor with color 1. */
InRegs.x.cx = 0;
int86(0x10, &InRegs, &OutRegs);
InRegs.x.dx = Y;
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor with color 1. */
InRegs.x.cx = 1;
int86(0x10, &InRegs, &OutRegs);
if (Y == ScreenYMax - 1) {/* Last row - clear all marks we made. */
for (i = 0; i < ScreenYMax; i++) {
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor back with color 1. */
InRegs.x.dx = i;
InRegs.x.cx = 0;
int86(0x10, &InRegs, &OutRegs);
InRegs.h.bh = 0;
InRegs.h.ah = 0x0c; /* BIOS Write dot (xor mode). */
InRegs.h.al = 0x81; /* Xor back with color 1. */
InRegs.x.dx = i;
InRegs.x.cx = 1;
int86(0x10, &InRegs, &OutRegs);
}
}
break;
#endif /* __MSDOS__ */
#ifdef __SGI_GL__
case GIF_DUMP_SGI_WINDOW:
memcpy(ScanLine, GlblGifBufferPtr, ScreenXMax * sizeof(GifPixelType));
GlblGifBufferPtr -= ScreenXMax;
break;
#endif /* __SGI_GL__ */
#ifdef __X11__
case GIF_DUMP_X_WINDOW:
memcpy(ScanLine, GlblGifBufferPtr, ScreenXMax * sizeof(GifPixelType));
GlblGifBufferPtr += ScreenXMax;
break;
#endif /* __X11__ */
default:
break;
}
}
/******************************************************************************
* Handle last GIF error. Try to close the file and free all allocated memory. *
******************************************************************************/
static int HandleGifError(GifFileType *GifFile)
{
int i = GifLastError();
if (EGifCloseFile(GifFile) == GIF_ERROR) {
GifLastError();
}
return i;
}

837
G/LIB/DGIF_LIB.C Normal file
View File

@ -0,0 +1,837 @@
/******************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 *
*******************************************************************************
* The kernel of the GIF Decoding process can be found here. *
*******************************************************************************
* History: *
* 16 Jun 89 - Version 1.0 by Gershon Elber. *
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
******************************************************************************/
#ifdef __MSDOS__
#include <io.h>
#include <alloc.h>
#include <stdlib.h>
#include <sys\stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif /* __MSDOS__ */
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_hash.h"
#define PROGRAM_NAME "GIF_LIBRARY"
#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for comment. */
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define FILE_STATE_READ 0x01/* 1 write, 0 read - EGIF_LIB compatible.*/
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
#define IS_READABLE(Private) (!(Private -> FileState & FILE_STATE_READ))
typedef struct GifFilePrivateType {
int FileState,
FileHandle, /* Where all this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at list this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits,/* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord, /* For bytes decomposition into codes. */
PixelCount; /* Number of pixels in image. */
FILE *File; /* File as stream. */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE+1]; /* So we can trace the codes. */
unsigned int Prefix[LZ_MAX_CODE+1];
} GifFilePrivateType;
#ifdef SYSV
static char *VersionStr =
"Gif library module,\t\tGershon Elber\n\
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#else
static char *VersionStr =
PROGRAM_NAME
" IBMPC "
GIF_LIB_VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#endif /* SYSV */
extern int _GifError;
static int DGifGetWord(FILE *File, int *Word);
static int DGifSetupDecompress(GifFileType *GifFile);
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen);
static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode);
static int DGifDecompressInput(GifFilePrivateType *Private, int *Code);
static int DGifBufferedInput(FILE *File, GifByteType *Buf,
GifByteType *NextByte);
/******************************************************************************
* Open a new gif file for read, given by its name. *
* Returns GifFileType pointer dynamically allocated which serves as the gif *
* info record. _GifError is cleared if succesfull. *
******************************************************************************/
GifFileType *DGifOpenFileName(char *FileName)
{
int FileHandle;
if ((FileHandle = open(FileName, O_RDONLY
#ifdef __MSDOS__
| O_BINARY
#endif /* __MSDOS__ */
)) == -1) {
_GifError = D_GIF_ERR_OPEN_FAILED;
return NULL;
}
return DGifOpenFileHandle(FileHandle);
}
/******************************************************************************
* Update a new gif file, given its file handle. *
* Returns GifFileType pointer dynamically allocated which serves as the gif *
* info record. _GifError is cleared if succesfull. *
******************************************************************************/
GifFileType *DGifOpenFileHandle(int FileHandle)
{
char Buf[GIF_STAMP_LEN+1];
GifFileType *GifFile;
GifFilePrivateType *Private;
FILE *f;
#ifdef __MSDOS__
setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);/* And inc. stream buffer.*/
#else
f = fdopen(FileHandle, "r"); /* Make it into a stream: */
#endif /* __MSDOS__ */
if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) {
_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
if ((Private = (GifFilePrivateType *) malloc(sizeof(GifFilePrivateType)))
== NULL) {
_GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
free((char *) GifFile);
return NULL;
}
GifFile -> Private = (VoidPtr) Private;
GifFile -> SColorMap = GifFile -> IColorMap = NULL;
Private -> FileHandle = FileHandle;
Private -> File = f;
Private -> FileState = 0; /* Make sure bit 0 = 0 (File open for read). */
/* Lets see if this is GIF file: */
if (fread(Buf, 1, GIF_STAMP_LEN, Private -> File) != GIF_STAMP_LEN) {
_GifError = D_GIF_ERR_READ_FAILED;
free((char *) Private);
free((char *) GifFile);
return NULL;
}
/* The GIF Version number is ignored at this time. Maybe we should do */
/* something more useful with it. */
Buf[GIF_STAMP_LEN] = 0;
if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
_GifError = D_GIF_ERR_NOT_GIF_FILE;
free((char *) Private);
free((char *) GifFile);
return NULL;
}
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
free((char *) Private);
free((char *) GifFile);
return NULL;
}
_GifError = 0;
return GifFile;
}
/******************************************************************************
* This routine should be called before any other DGif calls. Note that *
* this routine is called automatically from DGif file open routines. *
******************************************************************************/
int DGifGetScreenDesc(GifFileType *GifFile)
{
int Size, i;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
/* Put the screen descriptor into the file: */
if (DGifGetWord(Private -> File, &GifFile -> SWidth) == GIF_ERROR ||
DGifGetWord(Private -> File, &GifFile -> SHeight) == GIF_ERROR)
return GIF_ERROR;
if (fread(Buf, 1, 3, Private -> File) != 3) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
GifFile -> SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
GifFile -> SBitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile -> SBackGroundColor = Buf[1];
if (Buf[0] & 0x80) { /* Do we have global color map? */
Size = (1 << GifFile -> SBitsPerPixel);
GifFile -> SColorMap =
(GifColorType *) malloc(sizeof(GifColorType) * Size);
for (i = 0; i < Size; i++) { /* Get the global color map: */
if (fread(Buf, 1, 3, Private -> File) != 3) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
GifFile -> SColorMap[i].Red = Buf[0];
GifFile -> SColorMap[i].Green = Buf[1];
GifFile -> SColorMap[i].Blue = Buf[2];
}
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attemp to read an image. *
******************************************************************************/
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *Type)
{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (fread(&Buf, 1, 1, Private -> File) != 1) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
switch (Buf) {
case ',':
*Type = IMAGE_DESC_RECORD_TYPE;
break;
case '!':
*Type = EXTENSION_RECORD_TYPE;
break;
case ';':
*Type = TERMINATE_RECORD_TYPE;
break;
default:
*Type = UNDEFINED_RECORD_TYPE;
_GifError = D_GIF_ERR_WRONG_RECORD;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attemp to read an image. *
* Note it is assumed the Image desc. header (',') has been read. *
******************************************************************************/
int DGifGetImageDesc(GifFileType *GifFile)
{
int Size, i;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (DGifGetWord(Private -> File, &GifFile -> ILeft) == GIF_ERROR ||
DGifGetWord(Private -> File, &GifFile -> ITop) == GIF_ERROR ||
DGifGetWord(Private -> File, &GifFile -> IWidth) == GIF_ERROR ||
DGifGetWord(Private -> File, &GifFile -> IHeight) == GIF_ERROR)
return GIF_ERROR;
if (fread(Buf, 1, 1, Private -> File) != 1) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
GifFile -> IBitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile -> IInterlace = (Buf[0] & 0x40);
if (Buf[0] & 0x80) { /* Does this image have local color map? */
Size = (1 << GifFile -> IBitsPerPixel);
if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
GifFile -> IColorMap =
(GifColorType *) malloc(sizeof(GifColorType) * Size);
for (i = 0; i < Size; i++) { /* Get the image local color map: */
if (fread(Buf, 1, 3, Private -> File) != 3) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
GifFile -> IColorMap[i].Red = Buf[0];
GifFile -> IColorMap[i].Green = Buf[1];
GifFile -> IColorMap[i].Blue = Buf[2];
}
}
Private -> PixelCount = (long) GifFile -> IWidth *
(long) GifFile -> IHeight;
DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
return GIF_OK;
}
/******************************************************************************
* Get one full scanned line (Line) of length LineLen from GIF file. *
******************************************************************************/
int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
{
GifByteType *Dummy;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (!LineLen) LineLen = GifFile -> IWidth;
#ifdef __MSDOS__
if ((Private -> PixelCount -= LineLen) > 0xffff0000UL) {
#else
if ((Private -> PixelCount -= LineLen) > 0xffff0000) {
#endif /* __MSDOS__ */
_GifError = D_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
if (Private -> PixelCount == 0) {
/* We probably would not be called any more, so lets clean */
/* everything before we return: need to flush out all rest of */
/* image until empty block (size 0) detected. We use GetCodeNext.*/
do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
while (Dummy != NULL);
}
return GIF_OK;
}
else
return GIF_ERROR;
}
/******************************************************************************
* Put one pixel (Pixel) into GIF file. *
******************************************************************************/
int DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
{
GifByteType *Dummy;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
#ifdef __MSDOS__
if (--Private -> PixelCount > 0xffff0000UL)
#else
if (--Private -> PixelCount > 0xffff0000)
#endif /* __MSDOS__ */
{
_GifError = D_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
if (Private -> PixelCount == 0) {
/* We probably would not be called any more, so lets clean */
/* everything before we return: need to flush out all rest of */
/* image until empty block (size 0) detected. We use GetCodeNext.*/
do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
while (Dummy != NULL);
}
return GIF_OK;
}
else
return GIF_ERROR;
}
/******************************************************************************
* Get an extension block (see GIF manual) from gif file. This routine only *
* returns the first data block, and DGifGetExtensionNext shouldbe called *
* after this one until NULL extension is returned. *
* The Extension should NOT be freed by the user (not dynamically allocated).*
* Note it is assumed the Extension desc. header ('!') has been read. *
******************************************************************************/
int DGifGetExtension(GifFileType *GifFile, int *ExtCode,
GifByteType **Extension)
{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (fread(&Buf, 1, 1, Private -> File) != 1) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
*ExtCode = Buf;
return DGifGetExtensionNext(GifFile, Extension);
}
/******************************************************************************
* Get a following extension block (see GIF manual) from gif file. This *
* routine sould be called until NULL Extension is returned. *
* The Extension should NOT be freed by the user (not dynamically allocated).*
******************************************************************************/
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **Extension)
{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (fread(&Buf, 1, 1, Private -> File) != 1) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
if (Buf > 0) {
*Extension = Private -> Buf; /* Use private unused buffer. */
(*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (fread(&((*Extension)[1]), 1, Buf, Private -> File) != Buf) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
}
else
*Extension = NULL;
return GIF_OK;
}
/******************************************************************************
* This routine should be called last, to close GIF file. *
******************************************************************************/
int DGifCloseFile(GifFileType *GifFile)
{
GifFilePrivateType *Private;
FILE *File;
if (GifFile == NULL) return GIF_ERROR;
Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
File = Private -> File;
if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
if (GifFile -> SColorMap) free((char *) GifFile -> SColorMap);
if (Private) free((char *) Private);
free(GifFile);
if (fclose(File) != 0) {
_GifError = D_GIF_ERR_CLOSE_FAILED;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* Get 2 bytes (word) from the given file: *
******************************************************************************/
static int DGifGetWord(FILE *File, int *Word)
{
unsigned char c[2];
if (fread(c, 1, 2, File) != 2) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
*Word = (((unsigned int) c[1]) << 8) + c[0];
return GIF_OK;
}
/******************************************************************************
* Get the image code in compressed form. his routine can be called if the *
* information needed to be piped out as is. Obviously this is much faster *
* than decoding and encoding again. This routine should be followed by calls *
* to DGifGetCodeNext, until NULL block is returned. *
* The block should NOT be freed by the user (not dynamically allocated). *
******************************************************************************/
int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
{
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
*CodeSize = Private -> BitsPerPixel;
return DGifGetCodeNext(GifFile, CodeBlock);
}
/******************************************************************************
* Continue to get the image code in compressed form. This routine should be *
* called until NULL block is returned. *
* The block should NOT be freed by the user (not dynamically allocated). *
******************************************************************************/
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (fread(&Buf, 1, 1, Private -> File) != 1) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
if (Buf > 0) {
*CodeBlock = Private -> Buf; /* Use private unused buffer. */
(*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (fread(&((*CodeBlock)[1]), 1, Buf, Private -> File) != Buf) {
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
}
else {
*CodeBlock = NULL;
Private -> Buf[0] = 0; /* Make sure the buffer is empty! */
Private -> PixelCount = 0; /* And local info. indicate image read. */
}
return GIF_OK;
}
/******************************************************************************
* Setup the LZ decompression for this image: *
******************************************************************************/
static int DGifSetupDecompress(GifFileType *GifFile)
{
int i, BitsPerPixel;
GifByteType CodeSize;
unsigned int *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
fread(&CodeSize, 1, 1, Private -> File); /* Read Code size from file. */
BitsPerPixel = CodeSize;
Private -> Buf[0] = 0; /* Input Buffer empty. */
Private -> BitsPerPixel = BitsPerPixel;
Private -> ClearCode = (1 << BitsPerPixel);
Private -> EOFCode = Private -> ClearCode + 1;
Private -> RunningCode = Private -> EOFCode + 1;
Private -> RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
Private -> MaxCode1 = 1 << Private -> RunningBits; /* Max. code + 1. */
Private -> StackPtr = 0; /* No pixels on the pixel stack. */
Private -> LastCode = NO_SUCH_CODE;
Private -> CrntShiftState = 0; /* No information in CrntShiftDWord. */
Private -> CrntShiftDWord = 0;
Prefix = Private -> Prefix;
for (i = 0; i <= LZ_MAX_CODE; i++) Prefix[i] = NO_SUCH_CODE;
return GIF_OK;
}
/******************************************************************************
* The LZ decompression routine: *
* This version decompress the given gif file into Line of length LineLen. *
* This routine can be called few times (one per scan line, for example), in *
* order the complete the whole image. *
******************************************************************************/
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen)
{
int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
GifByteType *Stack, *Suffix;
unsigned int *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
StackPtr = Private -> StackPtr;
Prefix = Private -> Prefix;
Suffix = Private -> Suffix;
Stack = Private -> Stack;
EOFCode = Private -> EOFCode;
ClearCode = Private -> ClearCode;
LastCode = Private -> LastCode;
if (StackPtr != 0) {
/* Let pop the stack off before continueing to read the gif file: */
while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr];
}
while (i < LineLen) { /* Decode LineLen items. */
if (DGifDecompressInput(Private, &CrntCode) == GIF_ERROR)
return GIF_ERROR;
if (CrntCode == EOFCode) {
/* Note however that usually we will not be here as we will stop */
/* decoding as soon as we got all the pixel, or EOF code will */
/* not be read at all, and DGifGetLine/Pixel clean everything. */
if (i != LineLen - 1 || Private -> PixelCount != 0) {
_GifError = D_GIF_ERR_EOF_TOO_SOON;
return GIF_ERROR;
}
i++;
}
else if (CrntCode == ClearCode) {
/* We need to start over again: */
for (j = 0; j <= LZ_MAX_CODE; j++) Prefix[j] = NO_SUCH_CODE;
Private -> RunningCode = Private -> EOFCode + 1;
Private -> RunningBits = Private -> BitsPerPixel + 1;
Private -> MaxCode1 = 1 << Private -> RunningBits;
LastCode = Private -> LastCode = NO_SUCH_CODE;
}
else {
/* Its regular code - if in pixel range simply add it to output */
/* stream, otherwise trace to codes linked list until the prefix */
/* is in pixel range: */
if (CrntCode < ClearCode) {
/* This is simple - its pixel scalar, so add it to output: */
Line[i++] = CrntCode;
}
else {
/* Its a code to needed to be traced: trace the linked list */
/* until the prefix is a pixel, while pushing the suffix */
/* pixels on our stack. If we done, pop the stack in reverse */
/* (thats what stack is good for!) order to output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
/* Only allowed if CrntCode is exactly the running code: */
/* In that case CrntCode = XXXCode, CrntCode or the */
/* prefix code is last code and the suffix char is */
/* exactly the prefix of last code! */
if (CrntCode == Private -> RunningCode - 2) {
CrntPrefix = LastCode;
Suffix[Private -> RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
LastCode, ClearCode);
}
else {
_GifError = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
}
else
CrntPrefix = CrntCode;
/* Now (if image is O.K.) we should not get an NO_SUCH_CODE */
/* During the trace. As we might loop forever, in case of */
/* defective image, we count the number of loops we trace */
/* and stop if we got LZ_MAX_CODE. obviously we can not */
/* loop more than that. */
j = 0;
while (j++ <= LZ_MAX_CODE &&
CrntPrefix > ClearCode &&
CrntPrefix <= LZ_MAX_CODE) {
Stack[StackPtr++] = Suffix[CrntPrefix];
CrntPrefix = Prefix[CrntPrefix];
}
if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
_GifError = D_GIF_ERR_IMAGE_DEFECT;
return GIF_ERROR;
}
/* Push the last character on stack: */
Stack[StackPtr++] = CrntPrefix;
/* Now lets pop all the stack into output: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
if (LastCode != NO_SUCH_CODE) {
Prefix[Private -> RunningCode - 2] = LastCode;
if (CrntCode == Private -> RunningCode - 2) {
/* Only allowed if CrntCode is exactly the running code: */
/* In that case CrntCode = XXXCode, CrntCode or the */
/* prefix code is last code and the suffix char is */
/* exactly the prefix of last code! */
Suffix[Private -> RunningCode - 2] =
DGifGetPrefixChar(Prefix, LastCode, ClearCode);
}
else {
Suffix[Private -> RunningCode - 2] =
DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
}
}
LastCode = CrntCode;
}
}
Private -> LastCode = LastCode;
Private -> StackPtr = StackPtr;
return GIF_OK;
}
/******************************************************************************
* Routine to trace the Prefixes linked list until we get a prefix which is *
* not code, but a pixel value (less than ClearCode). Returns that pixel value.*
* If image is defective, we might loop here forever, so we limit the loops to *
* the maximum possible if image O.k. - LZ_MAX_CODE times. *
******************************************************************************/
static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode)
{
int i = 0;
while (Code > ClearCode && i++ <= LZ_MAX_CODE) Code = Prefix[Code];
return Code;
}
/******************************************************************************
* Interface for accessing the LZ codes directly. Set Code to the real code *
* (12bits), or to -1 if EOF code is returned. *
******************************************************************************/
int DGifGetLZCodes(GifFileType *GifFile, int *Code)
{
GifByteType *CodeBlock;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_READABLE(Private)) {
/* This file was NOT open for reading: */
_GifError = D_GIF_ERR_NOT_READABLE;
return GIF_ERROR;
}
if (DGifDecompressInput(Private, Code) == GIF_ERROR)
return GIF_ERROR;
if (*Code == Private -> EOFCode) {
/* Skip rest of codes (hopefully only NULL terminating block): */
do if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
return GIF_ERROR;
while (CodeBlock != NULL);
*Code = -1;
}
else if (*Code == Private -> ClearCode) {
/* We need to start over again: */
Private -> RunningCode = Private -> EOFCode + 1;
Private -> RunningBits = Private -> BitsPerPixel + 1;
Private -> MaxCode1 = 1 << Private -> RunningBits;
}
return GIF_OK;
}
/******************************************************************************
* The LZ decompression input routine: *
* This routine is responsable for the decompression of the bit stream from *
* 8 bits (bytes) packets, into the real codes. *
* Returns GIF_OK if read succesfully. *
******************************************************************************/
static int DGifDecompressInput(GifFilePrivateType *Private, int *Code)
{
GifByteType NextByte;
static unsigned int CodeMasks[] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000f, 0x001f, 0x003f, 0x007f,
0x00ff, 0x01ff, 0x03ff, 0x07ff,
0x0fff
};
while (Private -> CrntShiftState < Private -> RunningBits) {
/* Needs to get more bytes from input stream for next code: */
if (DGifBufferedInput(Private -> File, Private -> Buf, &NextByte)
== GIF_ERROR) {
return GIF_ERROR;
}
Private -> CrntShiftDWord |=
((unsigned long) NextByte) << Private -> CrntShiftState;
Private -> CrntShiftState += 8;
}
*Code = Private -> CrntShiftDWord & CodeMasks[Private -> RunningBits];
Private -> CrntShiftDWord >>= Private -> RunningBits;
Private -> CrntShiftState -= Private -> RunningBits;
/* If code cannt fit into RunningBits bits, must raise its size. Note */
/* however that codes above 4095 are used for special signaling. */
if (++Private -> RunningCode > Private -> MaxCode1 &&
Private -> RunningBits < LZ_BITS) {
Private -> MaxCode1 <<= 1;
Private -> RunningBits++;
}
return GIF_OK;
}
/******************************************************************************
* This routines read one gif data block at a time and buffers it internally *
* so that the decompression routine could access it. *
* The routine returns the next byte from its internal buffer (or read next *
* block in if buffer empty) and returns GIF_OK if succesful. *
******************************************************************************/
static int DGifBufferedInput(FILE *File, GifByteType *Buf,
GifByteType *NextByte)
{
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
if (fread(Buf, 1, 1, File) != 1)
{
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
if (fread(&Buf[1], 1, Buf[0], File) != Buf[0])
{
_GifError = D_GIF_ERR_READ_FAILED;
return GIF_ERROR;
}
*NextByte = Buf[1];
Buf[1] = 2; /* We use now the second place as last char read! */
Buf[0]--;
}
else {
*NextByte = Buf[Buf[1]++];
Buf[0]--;
}
return GIF_OK;
}

774
G/LIB/EGIF_LIB.C Normal file
View File

@ -0,0 +1,774 @@
/******************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber Ver 1.1, Aug. 1990 *
*******************************************************************************
* The kernel of the GIF Encoding process can be found here. *
*******************************************************************************
* History: *
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
******************************************************************************/
#ifdef __MSDOS__
#include <io.h>
#include <alloc.h>
#include <sys\stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#ifdef R6000
#include <sys/mode.h>
#endif
#endif /* __MSDOS__ */
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_hash.h"
#define PROGRAM_NAME "GIF_LIBRARY"
#define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for comment. */
#define GIF_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define ZL_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define FILE_STATE_WRITE 0x01/* 1 write, 0 read - DGIF_LIB compatible.*/
#define FILE_STATE_SCREEN 0x02
#define FILE_STATE_IMAGE 0x04
#define FLUSH_OUTPUT 4096 /* Impossible code, to signal flush. */
#define FIRST_CODE 4097 /* Impossible code, to signal first. */
#define IS_WRITEABLE(Private) (Private -> FileState & FILE_STATE_WRITE)
/* #define DEBUG_NO_PREFIX Dump only compressed data. */
typedef struct GifFilePrivateType {
int FileState,
FileHandle, /* Where old this data goes to! */
BitsPerPixel, /* Bits per pixel (Codes uses at list this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits,/* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
CrntCode, /* Current algorithm code. */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord, /* For bytes decomposition into codes. */
PixelCount;
FILE *File; /* File as stream. */
GifByteType Buf[256]; /* Compressed output is buffered here. */
GifHashTableType *HashTable;
} GifFilePrivateType;
extern int _GifError;
/* Masks given codes to BitsPerPixel, to make sure all codes are in range: */
static GifPixelType CodeMask[] = {
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
};
#ifdef SYSV
static char *VersionStr =
"Gif library module,\t\tGershon Elber\n\
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#else
static char *VersionStr =
PROGRAM_NAME
" IBMPC "
GIF_LIB_VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#endif /* SYSV */
static char *GifVersionPrefix = GIF_STAMP;
static int EGifPutWord(int Word, FILE *File);
static int EGifSetupCompress(GifFileType *GifFile);
static int EGifCompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen);
static int EGifCompressOutput(GifFilePrivateType *Private, int Code);
static int EGifBufferedOutput(FILE *File, GifByteType *Buf, int c);
/******************************************************************************
* Open a new gif file for write, given by its name. If TestExistance then *
* if the file exists this routines fails (returns NULL). *
* Returns GifFileType pointer dynamically allocated which serves as the gif *
* info record. _GifError is cleared if succesfull. *
******************************************************************************/
GifFileType *EGifOpenFileName(char *FileName, int TestExistance)
{
int FileHandle;
if (TestExistance)
FileHandle = open(FileName,
O_WRONLY | O_CREAT | O_EXCL
#ifdef __MSDOS__
| O_BINARY
#endif /* __MSDOS__ */
,
S_IREAD | S_IWRITE);
else
FileHandle = open(FileName,
O_WRONLY | O_CREAT | O_TRUNC
#ifdef __MSDOS__
| O_BINARY
#endif /* __MSDOS__ */
,
S_IREAD | S_IWRITE);
if (FileHandle == -1) {
_GifError = E_GIF_ERR_OPEN_FAILED;
return NULL;
}
return EGifOpenFileHandle(FileHandle);
}
/******************************************************************************
* Update a new gif file, given its file handle, which must be opened for *
* write in binary mode. *
* Returns GifFileType pointer dynamically allocated which serves as the gif *
* info record. _GifError is cleared if succesfull. *
******************************************************************************/
GifFileType *EGifOpenFileHandle(int FileHandle)
{
GifFileType *GifFile;
GifFilePrivateType *Private;
FILE *f;
#ifdef __MSDOS__
setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
f = fdopen(FileHandle, "wb"); /* Make it into a stream: */
setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream buffer. */
#else
f = fdopen(FileHandle, "w"); /* Make it into a stream: */
#endif /* __MSDOS__ */
if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) {
_GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
GifFile -> SWidth = GifFile -> SHeight =
GifFile -> SColorResolution = GifFile -> SBitsPerPixel =
GifFile -> SBackGroundColor =
GifFile -> ILeft = GifFile -> ITop = GifFile -> IWidth = GifFile -> IHeight =
GifFile -> IInterlace =
GifFile -> IBitsPerPixel = 0;
GifFile -> SColorMap = GifFile -> IColorMap = NULL;
#ifndef DEBUG_NO_PREFIX
if (fwrite(GifVersionPrefix, 1, strlen(GifVersionPrefix), f) !=
strlen(GifVersionPrefix)) {
_GifError = E_GIF_ERR_WRITE_FAILED;
free((char *) GifFile);
return NULL;
}
#endif /* DEBUG_NO_PREFIX */
if ((Private = (GifFilePrivateType *) malloc(sizeof(GifFilePrivateType)))
== NULL) {
_GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
GifFile -> Private = (VoidPtr) Private;
Private -> FileHandle = FileHandle;
Private -> File = f;
Private -> FileState = FILE_STATE_WRITE;
if ((Private -> HashTable = _InitHashTable()) == NULL) {
_GifError = E_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
_GifError = 0;
return GifFile;
}
/******************************************************************************
* Routine to set current GIF version. All files open for write will be *
* using this version until next call to this routine. Version consists of *
* 3 characters as "87a" or "89a". No test is made to validate the version. *
******************************************************************************/
void EGifSetGifVersion(char *Version)
{
strncpy(&GifVersionPrefix[3], Version, 3);
}
/******************************************************************************
* This routine should be called before any other EGif calls, immediately *
* follows the GIF file openning. *
******************************************************************************/
int EGifPutScreenDesc(GifFileType *GifFile,
int Width, int Height, int ColorRes, int BackGround,
int BitsPerPixel, GifColorType *ColorMap)
{
int i, Size;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (Private -> FileState & FILE_STATE_SCREEN) {
/* If already has screen descriptor - something is wrong! */
_GifError = E_GIF_ERR_HAS_SCRN_DSCR;
return GIF_ERROR;
}
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
GifFile -> SWidth = Width;
GifFile -> SHeight = Height;
GifFile -> SColorResolution = ColorRes;
GifFile -> SBitsPerPixel = BitsPerPixel;
GifFile -> SBackGroundColor = BackGround;
if (ColorMap) {
Size = sizeof(GifColorType) * (1 << BitsPerPixel);
GifFile -> SColorMap = (GifColorType *) malloc(Size);
memcpy(GifFile -> SColorMap, ColorMap, Size);
}
/* Put the screen descriptor into the file: */
EGifPutWord(Width, Private -> File);
EGifPutWord(Height, Private -> File);
Buf[0] = (ColorMap ? 0x80 : 0x00) |
((ColorRes - 1) << 4) |
(BitsPerPixel - 1);
Buf[1] = BackGround;
Buf[2] = 0;
#ifndef DEBUG_NO_PREFIX
fwrite(Buf, 1, 3, Private -> File);
#endif /* DEBUG_NO_PREFIX */
/* If we have Global color map - dump it also: */
#ifndef DEBUG_NO_PREFIX
if (ColorMap != NULL)
for (i = 0; i < (1 << BitsPerPixel); i++) {
/* Put the ColorMap out also: */
Buf[0] = ColorMap[i].Red;
Buf[1] = ColorMap[i].Green;
Buf[2] = ColorMap[i].Blue;
if (fwrite(Buf, 1, 3, Private -> File) != 3) {
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
}
#endif /* DEBUG_NO_PREFIX */
/* Mark this file as has screen descriptor, and no pixel written yet: */
Private -> FileState |= FILE_STATE_SCREEN;
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attemp to dump an image - any *
* call to any of the pixel dump routines. *
******************************************************************************/
int EGifPutImageDesc(GifFileType *GifFile,
int Left, int Top, int Width, int Height, int Interlace,
int BitsPerPixel, GifColorType *ColorMap)
{
int i, Size;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (Private -> FileState & FILE_STATE_IMAGE &&
#ifdef __MSDOS__
Private -> PixelCount > 0xffff0000UL) {
#else
Private -> PixelCount > 0xffff0000) {
#endif /* __MSDOS__ */
/* If already has active image descriptor - something is wrong! */
_GifError = E_GIF_ERR_HAS_IMAG_DSCR;
return GIF_ERROR;
}
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
GifFile -> ILeft = Left;
GifFile -> ITop = Top;
GifFile -> IWidth = Width;
GifFile -> IHeight = Height;
GifFile -> IBitsPerPixel = BitsPerPixel;
GifFile -> IInterlace = Interlace;
if (ColorMap) {
Size = sizeof(GifColorType) * (1 << BitsPerPixel);
if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
GifFile -> IColorMap = (GifColorType *) malloc(Size);
memcpy(GifFile -> IColorMap, ColorMap, Size);
}
/* Put the image descriptor into the file: */
Buf[0] = ','; /* Image seperator character. */
#ifndef DEBUG_NO_PREFIX
fwrite(Buf, 1, 1, Private -> File);
#endif /* DEBUG_NO_PREFIX */
EGifPutWord(Left, Private -> File);
EGifPutWord(Top, Private -> File);
EGifPutWord(Width, Private -> File);
EGifPutWord(Height, Private -> File);
Buf[0] = (ColorMap ? 0x80 : 0x00) |
(Interlace ? 0x40 : 0x00) |
(BitsPerPixel - 1);
#ifndef DEBUG_NO_PREFIX
fwrite(Buf, 1, 1, Private -> File);
#endif /* DEBUG_NO_PREFIX */
/* If we have Global color map - dump it also: */
#ifndef DEBUG_NO_PREFIX
if (ColorMap != NULL)
for (i = 0; i < (1 << BitsPerPixel); i++) {
/* Put the ColorMap out also: */
Buf[0] = ColorMap[i].Red;
Buf[1] = ColorMap[i].Green;
Buf[2] = ColorMap[i].Blue;
if (fwrite(Buf, 1, 3, Private -> File) != 3) {
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
}
#endif /* DEBUG_NO_PREFIX */
if (GifFile -> SColorMap == NULL && GifFile -> IColorMap == NULL)
{
_GifError = E_GIF_ERR_NO_COLOR_MAP;
return GIF_ERROR;
}
/* Mark this file as has screen descriptor: */
Private -> FileState |= FILE_STATE_IMAGE;
Private -> PixelCount = (long) Width * (long) Height;
EGifSetupCompress(GifFile); /* Reset compress algorithm parameters. */
return GIF_OK;
}
/******************************************************************************
* Put one full scanned line (Line) of length LineLen into GIF file. *
******************************************************************************/
int EGifPutLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
{
int i;
GifPixelType Mask;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
if (!LineLen) LineLen = GifFile -> IWidth;
if ((Private -> PixelCount -= LineLen) < 0) {
_GifError = E_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
/* Make sure the codes are not out of bit range, as we might generate */
/* wrong code (because of overflow when we combine them) in this case: */
Mask = CodeMask[Private -> BitsPerPixel];
for (i = 0; i < LineLen; i++) Line[i] &= Mask;
return EGifCompressLine(GifFile, Line, LineLen);
}
/******************************************************************************
* Put one pixel (Pixel) into GIF file. *
******************************************************************************/
int EGifPutPixel(GifFileType *GifFile, GifPixelType Pixel)
{
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
if (--Private -> PixelCount < 0)
{
_GifError = E_GIF_ERR_DATA_TOO_BIG;
return GIF_ERROR;
}
/* Make sure the code is not out of bit range, as we might generate */
/* wrong code (because of overflow when we combine them) in this case: */
Pixel &= CodeMask[Private -> BitsPerPixel];
return EGifCompressLine(GifFile, &Pixel, 1);
}
/******************************************************************************
* Put a comment into GIF file using extension block. *
******************************************************************************/
int EGifPutComment(GifFileType *GifFile, char *Comment)
{
return EGifPutExtension(GifFile, COMMENT_EXT_FUNC_CODE, strlen(Comment),
Comment);
}
/******************************************************************************
* Put an extension block (see GIF manual) into gif file. *
******************************************************************************/
int EGifPutExtension(GifFileType *GifFile, int ExtCode, int ExtLen,
VoidPtr Extension)
{
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
Buf[0] = '!';
Buf[1] = ExtCode;
Buf[2] = ExtLen;
fwrite(Buf, 1, 3, Private -> File);
fwrite(Extension, 1, ExtLen, Private -> File);
Buf[0] = 0;
fwrite(Buf, 1, 1, Private -> File);
return GIF_OK;
}
/******************************************************************************
* Put the image code in compressed form. This routine can be called if the *
* information needed to be piped out as is. Obviously this is much faster *
* than decoding and encoding again. This routine should be followed by calls *
* to EGifPutCodeNext, until NULL block is given. *
* The block should NOT be freed by the user (not dynamically allocated). *
******************************************************************************/
int EGifPutCode(GifFileType *GifFile, int CodeSize, GifByteType *CodeBlock)
{
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
/* No need to dump code size as Compression set up does any for us: */
/*
Buf = CodeSize;
if (fwrite(&Buf, 1, 1, Private -> File) != 1) {
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
*/
return EGifPutCodeNext(GifFile, CodeBlock);
}
/******************************************************************************
* Continue to put the image code in compressed form. This routine should be *
* called with blocks of code as read via DGifGetCode/DGifGetCodeNext. If *
* given buffer pointer is NULL, empty block is written to mark end of code. *
******************************************************************************/
int EGifPutCodeNext(GifFileType *GifFile, GifByteType *CodeBlock)
{
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
if (CodeBlock != NULL) {
if (fwrite(CodeBlock, 1, CodeBlock[0] + 1, Private -> File)
!= CodeBlock[0] + 1) {
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
}
else {
Buf = 0;
if (fwrite(&Buf, 1, 1, Private -> File) != 1) {
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
Private -> PixelCount = 0; /* And local info. indicate image read. */
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called last, to close GIF file. *
******************************************************************************/
int EGifCloseFile(GifFileType *GifFile)
{
GifByteType Buf;
GifFilePrivateType *Private;
FILE *File;
if (GifFile == NULL) return GIF_ERROR;
Private = (GifFilePrivateType *) GifFile -> Private;
if (!IS_WRITEABLE(Private)) {
/* This file was NOT open for writing: */
_GifError = E_GIF_ERR_NOT_WRITEABLE;
return GIF_ERROR;
}
File = Private -> File;
Buf = ';';
fwrite(&Buf, 1, 1, Private -> File);
if (GifFile -> IColorMap) free((char *) GifFile -> IColorMap);
if (GifFile -> SColorMap) free((char *) GifFile -> SColorMap);
if (Private) {
if (Private -> HashTable) free((char *) Private -> HashTable);
free((char *) Private);
}
free(GifFile);
if (fclose(File) != 0) {
_GifError = E_GIF_ERR_CLOSE_FAILED;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* Put 2 bytes (word) into the given file: *
******************************************************************************/
static int EGifPutWord(int Word, FILE *File)
{
char c[2];
c[0] = Word & 0xff;
c[1] = (Word >> 8) & 0xff;
#ifndef DEBUG_NO_PREFIX
if (fwrite(c, 1, 2, File) == 2)
return GIF_OK;
else
return GIF_ERROR;
#else
return GIF_OK;
#endif /* DEBUG_NO_PREFIX */
}
/******************************************************************************
* Setup the LZ compression for this image: *
******************************************************************************/
static int EGifSetupCompress(GifFileType *GifFile)
{
int BitsPerPixel;
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
/* Test and see what color map to use, and from it # bits per pixel: */
if (GifFile -> IColorMap)
BitsPerPixel = GifFile -> IBitsPerPixel;
else if (GifFile -> SColorMap)
BitsPerPixel = GifFile -> SBitsPerPixel;
else {
_GifError = E_GIF_ERR_NO_COLOR_MAP;
return GIF_ERROR;
}
Buf = BitsPerPixel = (BitsPerPixel < 2 ? 2 : BitsPerPixel);
fwrite(&Buf, 1, 1, Private -> File); /* Write the Code size to file. */
Private -> Buf[0] = 0; /* Nothing was output yet. */
Private -> BitsPerPixel = BitsPerPixel;
Private -> ClearCode = (1 << BitsPerPixel);
Private -> EOFCode = Private -> ClearCode + 1;
Private -> RunningCode = Private -> EOFCode + 1;
Private -> RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
Private -> MaxCode1 = 1 << Private -> RunningBits; /* Max. code + 1. */
Private -> CrntCode = FIRST_CODE; /* Signal that this is first one! */
Private -> CrntShiftState = 0; /* No information in CrntShiftDWord. */
Private -> CrntShiftDWord = 0;
/* Clear hash table and send Clear to make sure the decoder do the same. */
_ClearHashTable(Private -> HashTable);
if (EGifCompressOutput(Private, Private -> ClearCode) == GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* The LZ compression routine: *
* This version compress the given buffer Line of length LineLen. *
* This routine can be called few times (one per scan line, for example), in *
* order the complete the whole image. *
******************************************************************************/
static int EGifCompressLine(GifFileType *GifFile, GifPixelType *Line,
int LineLen)
{
int i = 0, CrntCode, NewCode;
unsigned long NewKey;
GifPixelType Pixel;
GifHashTableType *HashTable;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile -> Private;
HashTable = Private -> HashTable;
if (Private -> CrntCode == FIRST_CODE) /* Its first time! */
CrntCode = Line[i++];
else
CrntCode = Private -> CrntCode; /* Get last code in compression. */
while (i < LineLen) { /* Decode LineLen items. */
Pixel = Line[i++]; /* Get next pixel from stream. */
/* Form a new unique key to search hash table for the code combines */
/* CrntCode as Prefix string with Pixel as postfix char. */
NewKey = (((unsigned long) CrntCode) << 8) + Pixel;
if ((NewCode = _ExistsHashTable(HashTable, NewKey)) >= 0) {
/* This Key is already there, or the string is old one, so */
/* simple take new code as our CrntCode: */
CrntCode = NewCode;
}
else {
/* Put it in hash table, output the prefix code, and make our */
/* CrntCode equal to Pixel. */
if (EGifCompressOutput(Private, CrntCode)
== GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
CrntCode = Pixel;
/* If however the HashTable if full, we send a clear first and */
/* Clear the hash table. */
if (Private -> RunningCode >= ZL_MAX_CODE) {
/* Time to do some clearance: */
if (EGifCompressOutput(Private, Private -> ClearCode)
== GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
Private -> RunningCode = Private -> EOFCode + 1;
Private -> RunningBits = Private -> BitsPerPixel + 1;
Private -> MaxCode1 = 1 << Private -> RunningBits;
_ClearHashTable(HashTable);
}
else {
/* Put this unique key with its relative Code in hash table: */
_InsertHashTable(HashTable, NewKey, Private -> RunningCode++);
}
}
}
/* Preserve the current state of the compression algorithm: */
Private -> CrntCode = CrntCode;
if (Private -> PixelCount == 0)
{
/* We are done - output last Code and flush output buffers: */
if (EGifCompressOutput(Private, CrntCode)
== GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
if (EGifCompressOutput(Private, Private -> EOFCode)
== GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
if (EGifCompressOutput(Private, FLUSH_OUTPUT) == GIF_ERROR) {
_GifError = E_GIF_ERR_DISK_IS_FULL;
return GIF_ERROR;
}
}
return GIF_OK;
}
/******************************************************************************
* The LZ compression output routine: *
* This routine is responsable for the compression of the bit stream into *
* 8 bits (bytes) packets. *
* Returns GIF_OK if written succesfully. *
******************************************************************************/
static int EGifCompressOutput(GifFilePrivateType *Private, int Code)
{
int retval = GIF_OK;
if (Code == FLUSH_OUTPUT) {
while (Private -> CrntShiftState > 0) {
/* Get Rid of what is left in DWord, and flush it. */
if (EGifBufferedOutput(Private -> File, Private -> Buf,
Private -> CrntShiftDWord & 0xff) == GIF_ERROR)
retval = GIF_ERROR;
Private -> CrntShiftDWord >>= 8;
Private -> CrntShiftState -= 8;
}
Private -> CrntShiftState = 0; /* For next time. */
if (EGifBufferedOutput(Private -> File, Private -> Buf,
FLUSH_OUTPUT) == GIF_ERROR)
retval = GIF_ERROR;
}
else {
Private -> CrntShiftDWord |= ((long) Code) << Private -> CrntShiftState;
Private -> CrntShiftState += Private -> RunningBits;
while (Private -> CrntShiftState >= 8) {
/* Dump out full bytes: */
if (EGifBufferedOutput(Private -> File, Private -> Buf,
Private -> CrntShiftDWord & 0xff) == GIF_ERROR)
retval = GIF_ERROR;
Private -> CrntShiftDWord >>= 8;
Private -> CrntShiftState -= 8;
}
}
/* If code cannt fit into RunningBits bits, must raise its size. Note */
/* however that codes above 4095 are used for special signaling. */
if (Private -> RunningCode >= Private -> MaxCode1 && Code <= 4095) {
Private -> MaxCode1 = 1 << ++Private -> RunningBits;
}
return retval;
}
/******************************************************************************
* This routines buffers the given characters until 255 characters are ready *
* to be output. If Code is equal to -1 the buffer is flushed (EOF). *
* The buffer is Dumped with first byte as its size, as GIF format requires. *
* Returns GIF_OK if written succesfully. *
******************************************************************************/
static int EGifBufferedOutput(FILE *File, GifByteType *Buf, int c)
{
if (c == FLUSH_OUTPUT) {
/* Flush everything out. */
if (Buf[0] != 0 && fwrite(Buf, 1, Buf[0]+1, File) != Buf[0] + 1)
{
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
/* Mark end of compressed data, by an empty block (see GIF doc): */
Buf[0] = 0;
if (fwrite(Buf, 1, 1, File) != 1)
{
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
}
else {
if (Buf[0] == 255) {
/* Dump out this buffer - it is full: */
if (fwrite(Buf, 1, Buf[0] + 1, File) != Buf[0] + 1)
{
_GifError = E_GIF_ERR_WRITE_FAILED;
return GIF_ERROR;
}
Buf[0] = 0;
}
Buf[++Buf[0]] = c;
}
return GIF_OK;
}

632
G/LIB/GETARG.C Normal file
View File

@ -0,0 +1,632 @@
/***************************************************************************
* Routines to grab the parameters from the command line : *
* All the routines except the main one, starts with GA (Get Arguments) to *
* prevent from names conflicts. *
* It is assumed in these routine that any pointer, for any type has the *
* same length (i.e. length of int pointer is equal to char pointer etc.) *
* *
* The following routines are available in this module: *
* 1. int GAGetArgs(argc, argv, CtrlStr, Variables...) *
* where argc, argv as received on entry. *
* CtrlStr is the contrl string (see below) *
* Variables are all the variables to be set according to CtrlStr. *
* Note that all the variables MUST be transfered by address. *
* return 0 on correct parsing, otherwise error number (see GetArg.h). *
* 2. GAPrintHowTo(CtrlStr) *
* Print the control string to stderr, in the correct format needed. *
* This feature is very useful in case of error during GetArgs parsing. *
* Chars equal to SPACE_CHAR are not printed (regular spaces are NOT *
* allowed, and so using SPACE_CHAR you can create space in PrintHowTo). *
* 3. GAPrintErrMsg(Error) *
* Print the error to stderr, according to Error (usually returned by *
* GAGetArgs). *
* *
* CtrlStr format: *
* The control string passed to GetArgs controls the way argv (argc) are *
* parsed. Each entry in this string must not have any spaces in it. The *
* First Entry is the name of the program which is usually ignored except *
* when GAPrintHowTo is called. All the other entries (except the last one *
* which we will come back to it later) must have the following format: *
* 1. One letter which sets the option letter. *
* 2. '!' or '%' to determines if this option is really optional ('%') or *
* it must exists ('!')... *
* 3. '-' allways. *
* 4. Alpha numeric string, usually ignored, but used by GAPrintHowTo to *
* print the meaning of this input. *
* 5. Sequences starts with '!' or '%'. Again if '!' then this sequence *
* must exists (only if its option flag is given of course), and if '%' *
* it is optional. Each sequence will continue with one or two *
* characters which defines the kind of the input: *
* a. d, x, o, u - integer is expected (decimal, hex, octal base or *
* unsigned). *
* b. D, X, O, U - long integer is expected (same as above). *
* c. f - float number is expected. *
* d. F - double number is expected. *
* e. s - string is expected. *
* f. *? - any number of '?' kind (d, x, o, u, D, X, O, U, f, F, s) *
* will match this one. If '?' is numeric, it scans until *
* none numeric input is given. If '?' is 's' then it scans *
* up to the next option or end of argv. *
* *
* If the last parameter given in the CtrlStr, is not an option (i.e. the *
* second char is not in ['!', '%'] and the third one is not '-'), all what *
* remained from argv is linked to it. *
* *
* The variables passed to GAGetArgs (starting from 4th parameter) MUST *
* match the order of the CtrlStr: *
* For each option, one integer address must be passed. This integer must *
* initialized by 0. If that option is given in the command line, it will *
* be set to one. *
* In addition, the sequences that might follow an option require the *
* following parameters to pass: *
* 1. d, x, o, u - pointer to integer (int *). *
* 2. D, X, O, U - pointer to long (long *). *
* 3. f - pointer to float (float *). *
* 4. F - pointer to double (double *). *
* 5. s - pointer to char (char *). NO allocation is needed! *
* 6. *? - TWO variables are passed for each wild request. the first *
* one is (address of) integer, and it will return number of *
* parameters actually matched this sequence, and the second *
* one is a pointer to pointer to ? (? **), and will return an *
* address to a block of pointers to ? kind, terminated with *
* NULL pointer. NO pre-allocation is needed. *
* note that these two variables are pretty like the argv/argc *
* pair... *
* *
* Examples: *
* *
* "Example1 i%-OneInteger!d s%-Strings!*s j%- k!-Float!f Files" *
* Will match: Example1 -i 77 -s String1 String2 String3 -k 88.2 File1 File2*
* or match: Example1 -s String1 -k 88.3 -i 999 -j *
* but not: Example1 -i 77 78 (option i expects one integer, k must be). *
* Note the option k must exists, and that the order of the options is not *
* not important. In the first examples File1 & File2 will match the Files *
* in the command line. *
* A call to GAPrintHowTo with this CtrlStr will print to stderr: *
* Example1 [-i OneIngeter] [-s Strings...] [-j] -k Float Files... *
* *
* Notes: *
* *
* 1. This module assumes that all the pointers to all kind of data types *
* have the same length and format, i.e. sizeof(int *) == sizeof(char *).*
* *
* Gershon Elber Ver 0.2 Mar 88 *
****************************************************************************
* History: *
* 11 Mar 88 - Version 1.0 by Gershon Elber. *
***************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#include <alloc.h>
#endif /* __MSDOS__ */
#ifdef USE_VARARGS
#include <varargs.h>
#endif /* USE_VARARGS */
#include <stdio.h>
#include <string.h>
#include "getarg.h"
#define MYMALLOC /* If no "MyAlloc" routine elsewhere define this. */
#define MAX_PARAM 100 /* maximum number of parameters allowed. */
#define CTRL_STR_MAX_LEN 1024
#define SPACE_CHAR '|' /* The character not to print using HowTo. */
#ifndef TRUE
#define TRUE -1
#define FALSE 0
#endif /* TRUE */
#define ARG_OK 0
#define ISSPACE(x) ((x) <= ' ') /* Not conventional - but works fine! */
/* The two characters '%' and '!' are used in the control string: */
#define ISCTRLCHAR(x) (((x) == '%') || ((x) == '!'))
static char *GAErrorToken;/* On error code, ErrorToken is set to point on it.*/
static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr, int *argc,
char ***argv, int *Parameters[MAX_PARAM], int *ParamCount);
static int GAUpdateParameters(int *Parameters[], int *ParamCount,
char *Option, char *CtrlStrCopy, char *CtrlStr, int *argc,
char ***argv);
static int GAGetParmeters(int *Parameters[], int *ParamCount,
char *CtrlStrCopy , char *Option, int *argc, char ***argv);
static int GAGetMultiParmeters(int *Parameters[], int *ParamCount,
char *CtrlStrCopy, int *argc, char ***argv);
static void GASetParamCount(char *CtrlStr, int Max, int *ParamCount);
static void GAByteCopy(char *Dst, char *Src, unsigned n);
static int GAOptionExists(int argc, char **argv);
#ifdef MYMALLOC
static char *MyMalloc(unsigned size);
#endif /* MYMALLOC */
/***************************************************************************
* Routine to access the command line argument and interpret them: *
* Return ARG_OK (0) is case of succesfull parsing, error code else... *
***************************************************************************/
#ifdef USE_VARARGS
int GAGetArgs(int va_alist, ...)
{
va_list ap;
int argc, i, Error = FALSE, ParamCount = 0,
*Parameters[MAX_PARAM]; /* Save here parameter addresses. */
char **argv, *CtrlStr, *Option, CtrlStrCopy[CTRL_STR_MAX_LEN];
va_start(ap);
argc = va_arg(ap, int);
argv = va_arg(ap, char **);
CtrlStr = va_arg(ap, char *);
va_end(ap);
strcpy(CtrlStrCopy, CtrlStr);
/* Using base address of parameters we access other parameters addr: */
/* Note that me (for sure!) samples data beyond the current function */
/* frame, but we accesson these set address only by demand. */
for (i = 1; i <= MAX_PARAM; i++) Parameters[i-1] = va_arg(ap, int *);
#else
int GAGetArgs(int argc, char **argv, char *CtrlStr, ...)
{
int i, Error = FALSE, ParamCount = 0,
*Parameters[MAX_PARAM]; /* Save here parameter addresses. */
char *Option, CtrlStrCopy[CTRL_STR_MAX_LEN];
strcpy(CtrlStrCopy, CtrlStr);
/* Using base address of parameters we access other parameters addr: */
/* Note that me (for sure!) samples data beyond the current function */
/* frame, but we accesson these set address only by demand. */
for (i = 1; i <= MAX_PARAM; i++) Parameters[i-1] = (int *) *(i + &CtrlStr);
#endif /* USE_VARARG */
--argc; argv++; /* Skip the program name (first in argv/c list). */
while (argc >= 0) {
if (!GAOptionExists(argc, argv)) break; /* The loop. */
argc--;
Option = *argv++;
if ((Error = GAUpdateParameters(Parameters, &ParamCount, Option,
CtrlStrCopy, CtrlStr, &argc, &argv)) != FALSE) return Error;
}
/* Check for results and update trail of command line: */
return GATestAllSatis(CtrlStrCopy, CtrlStr, &argc, &argv, Parameters,
&ParamCount);
}
/***************************************************************************
* Routine to search for unsatisfied flags - simply scan the list for !- *
* sequence. Before this scan, this routine updates the rest of the command *
* line into the last two parameters if it is requested by the CtrlStr *
* (last item in CtrlStr is NOT an option). *
* Return ARG_OK if all satisfied, CMD_ERR_AllSatis error else. *
***************************************************************************/
static int GATestAllSatis(char *CtrlStrCopy, char *CtrlStr, int *argc,
char ***argv, int *Parameters[MAX_PARAM], int *ParamCount)
{
int i;
static char *LocalToken = NULL;
/* If LocalToken is not initialized - do it now. Note that this string */
/* should be writable as well so we can not assign it directly. */
if (LocalToken == NULL) {
LocalToken = (char *) malloc(3);
strcpy(LocalToken, "-?");
}
/* Check is last item is an option. If not then copy rest of command */
/* line into it as 1. NumOfprm, 2. pointer to block of pointers. */
for (i = strlen(CtrlStr) - 1; i > 0 && !ISSPACE(CtrlStr[i]); i--);
if (!ISCTRLCHAR(CtrlStr[i + 2])) {
GASetParamCount(CtrlStr, i, ParamCount); /* Point in correct prm.. */
*Parameters[(*ParamCount)++] = *argc;
GAByteCopy((char *) Parameters[(*ParamCount)++], (char *) argv,
sizeof(char *));
}
i = 0;
while (++i < strlen(CtrlStrCopy))
if ((CtrlStrCopy[i] == '-') && (CtrlStrCopy[i-1] == '!')) {
GAErrorToken = LocalToken;
LocalToken[1] = CtrlStrCopy[i-2]; /* Set the corrent flag. */
return CMD_ERR_AllSatis;
}
return ARG_OK;
}
/***************************************************************************
* Routine to update the parameters according to the given Option: *
***************************************************************************/
static int GAUpdateParameters(int *Parameters[], int *ParamCount,
char *Option, char *CtrlStrCopy, char *CtrlStr, int *argc, char ***argv)
{
int i, BooleanTrue = Option[2] != '-';
if (Option[0] != '-') {
GAErrorToken = Option;
return CMD_ERR_NotAnOpt;
}
i = 0; /* Scan the CtrlStrCopy for that option: */
while (i + 2 < strlen(CtrlStrCopy)) {
if ((CtrlStrCopy[i] == Option[1]) && (ISCTRLCHAR(CtrlStrCopy[i + 1]))
&& (CtrlStrCopy[i+2] == '-')) {
/* We found that option! */
break;
}
i++;
}
if (i + 2 >= strlen(CtrlStrCopy)) {
GAErrorToken = Option;
return CMD_ERR_NoSuchOpt;
}
/* If we are here, then we found that option in CtrlStr - Strip it off: */
CtrlStrCopy[i] = CtrlStrCopy[i + 1] = CtrlStrCopy[i + 2] = (char) ' ';
GASetParamCount(CtrlStr, i, ParamCount);/*Set it to point in correct prm.*/
i += 3;
/* Set boolean flag for that option. */
*Parameters[(*ParamCount)++] = BooleanTrue;
if (ISSPACE(CtrlStrCopy[i]))
return ARG_OK; /* Only a boolean flag is needed. */
/* Skip the text between the boolean option and data follows: */
while (!ISCTRLCHAR(CtrlStrCopy[i])) i++;
/* Get the parameters and return the appropriete return code: */
return GAGetParmeters(Parameters, ParamCount, &CtrlStrCopy[i],
Option, argc, argv);
}
/***************************************************************************
* Routine to get parameters according to the CtrlStr given from argv/c : *
***************************************************************************/
static int GAGetParmeters(int *Parameters[], int *ParamCount,
char *CtrlStrCopy , char *Option, int *argc, char ***argv)
{
int i = 0, ScanRes;
while (!(ISSPACE(CtrlStrCopy[i]))) {
switch (CtrlStrCopy[i+1]) {
case 'd': /* Get signed integers. */
ScanRes = sscanf(*((*argv)++), "%d",
(int *) Parameters[(*ParamCount)++]);
break;
case 'u': /* Get unsigned integers. */
ScanRes = sscanf(*((*argv)++), "%u",
(unsigned *) Parameters[(*ParamCount)++]);
break;
case 'x': /* Get hex integers. */
ScanRes = sscanf(*((*argv)++), "%x",
(int *) Parameters[(*ParamCount)++]);
break;
case 'o': /* Get octal integers. */
ScanRes = sscanf(*((*argv)++), "%o",
(int *) Parameters[(*ParamCount)++]);
break;
case 'D': /* Get signed long integers. */
ScanRes = sscanf(*((*argv)++), "%ld",
(long *) Parameters[(*ParamCount)++]);
break;
case 'U': /* Get unsigned long integers. */
ScanRes = sscanf(*((*argv)++), "%lu",
(unsigned long *) Parameters[(*ParamCount)++]);
break;
case 'X': /* Get hex long integers. */
ScanRes = sscanf(*((*argv)++), "%lx",
(long *) Parameters[(*ParamCount)++]);
break;
case 'O': /* Get octal long integers. */
ScanRes = sscanf(*((*argv)++), "%lo",
(long *) Parameters[(*ParamCount)++]);
break;
case 'f': /* Get float number. */
ScanRes = sscanf(*((*argv)++), "%f",
(float *) Parameters[(*ParamCount)++]);
case 'F': /* Get double float number. */
ScanRes = sscanf(*((*argv)++), "%lf",
(double *) Parameters[(*ParamCount)++]);
break;
case 's': /* It as a string. */
ScanRes = 1; /* Allways O.K. */
GAByteCopy((char *) Parameters[(*ParamCount)++],
(char *) ((*argv)++), sizeof(char *));
break;
case '*': /* Get few parameters into one: */
ScanRes = GAGetMultiParmeters(Parameters, ParamCount,
&CtrlStrCopy[i], argc, argv);
if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) {
GAErrorToken = Option;
return CMD_ERR_WildEmpty;
}
break;
default:
ScanRes = 0; /* Make optimizer warning silent. */
}
/* If reading fails and this number is a must (!) then error: */
if ((ScanRes == 0) && (CtrlStrCopy[i] == '!')) {
GAErrorToken = Option;
return CMD_ERR_NumRead;
}
if (CtrlStrCopy[i+1] != '*') {
(*argc)--; /* Everything is OK - update to next parameter: */
i += 2; /* Skip to next parameter (if any). */
}
else
i += 3; /* Skip the '*' also! */
}
return ARG_OK;
}
/***************************************************************************
* Routine to get few parameters into one pointer such that the returned *
* pointer actually points on a block of pointers to the parameters... *
* For example *F means a pointer to pointers on floats. *
* Returns number of parameters actually read. *
* This routine assumes that all pointers (on any kind of scalar) has the *
* same size (and the union below is totally ovelapped bteween dif. arrays) *
***************************************************************************/
static int GAGetMultiParmeters(int *Parameters[], int *ParamCount,
char *CtrlStrCopy, int *argc, char ***argv)
{
int i = 0, ScanRes, NumOfPrm = 0, **Pmain, **Ptemp;
union TmpArray { /* Save here the temporary data before copying it to */
int *IntArray[MAX_PARAM]; /* the returned pointer block. */
long *LngArray[MAX_PARAM];
float *FltArray[MAX_PARAM];
double *DblArray[MAX_PARAM];
char *ChrArray[MAX_PARAM];
} TmpArray;
do {
switch(CtrlStrCopy[2]) { /* CtrlStr == '!*?' or '%*?' where ? is. */
case 'd': /* Format to read the parameters: */
TmpArray.IntArray[NumOfPrm] = (int *) MyMalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%d",
(int *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'u':
TmpArray.IntArray[NumOfPrm] = (int *) MyMalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%u",
(unsigned int *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'o':
TmpArray.IntArray[NumOfPrm] = (int *) MyMalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%o",
(int *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'x':
TmpArray.IntArray[NumOfPrm] = (int *) MyMalloc(sizeof(int));
ScanRes = sscanf(*((*argv)++), "%x",
(int *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'D':
TmpArray.LngArray[NumOfPrm] = (long *) MyMalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%ld",
(long *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'U':
TmpArray.LngArray[NumOfPrm] = (long *) MyMalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lu",
(unsigned long *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'O':
TmpArray.LngArray[NumOfPrm] = (long *) MyMalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lo",
(long *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'X':
TmpArray.LngArray[NumOfPrm] = (long *) MyMalloc(sizeof(long));
ScanRes = sscanf(*((*argv)++), "%lx",
(long *) TmpArray.IntArray[NumOfPrm++]);
break;
case 'f':
TmpArray.FltArray[NumOfPrm] = (float *) MyMalloc(sizeof(float));
ScanRes = sscanf(*((*argv)++), "%f",
(float *) TmpArray.LngArray[NumOfPrm++]);
break;
case 'F':
TmpArray.DblArray[NumOfPrm] =
(double *) MyMalloc(sizeof(double));
ScanRes = sscanf(*((*argv)++), "%lf",
(double *) TmpArray.LngArray[NumOfPrm++]);
break;
case 's':
while ((*argc) && ((**argv)[0] != '-')) {
TmpArray.ChrArray[NumOfPrm++] = *((*argv)++);
(*argc)--;
}
ScanRes = 0; /* Force quit from do - loop. */
NumOfPrm++; /* Updated again immediately after loop! */
(*argv)++; /* "" */
break;
default:
ScanRes = 0; /* Make optimizer warning silent. */
}
(*argc)--;
}
while (ScanRes == 1); /* Exactly one parameter was read. */
(*argv)--; NumOfPrm--; (*argc)++;
/* Now allocate the block with the exact size, and set it: */
Ptemp = Pmain = (int **) MyMalloc((unsigned) (NumOfPrm+1) * sizeof(int *));
/* And here we use the assumption that all pointers are the same: */
for (i = 0; i < NumOfPrm; i++)
*Ptemp++ = TmpArray.IntArray[i];
*Ptemp = NULL; /* Close the block with NULL pointer. */
/* That it save the number of parameters read as first parameter to */
/* return and the pointer to the block as second, and return: */
*Parameters[(*ParamCount)++] = NumOfPrm;
GAByteCopy((char *) Parameters[(*ParamCount)++], (char *) &Pmain,
sizeof(char *));
return NumOfPrm;
}
/***************************************************************************
* Routine to scan the CtrlStr, upto Max and count the number of parameters *
* to that point: *
* 1. Each option is counted as one parameter - boolean variable (int) *
* 2. Within an option, each %? or !? is counted once - pointer to something*
* 3. Within an option, %*? or !*? is counted twice - one for item count *
* and one for pointer to block pointers. *
* Note ALL variables are passed by address and so of fixed size (address). *
***************************************************************************/
static void GASetParamCount(char *CtrlStr, int Max, int *ParamCount)
{
int i;
*ParamCount = 0;
for (i = 0; i < Max; i++) if (ISCTRLCHAR(CtrlStr[i])) {
if (CtrlStr[i+1] == '*')
*ParamCount += 2;
else
(*ParamCount)++;
}
}
/***************************************************************************
* Routine to copy exactly n bytes from Src to Dst. Note system library *
* routine strncpy should do the same, but it stops on NULL char ! *
***************************************************************************/
static void GAByteCopy(char *Dst, char *Src, unsigned n)
{
while (n--) *(Dst++) = *(Src++);
}
/***************************************************************************
* Routine to check if more option (i.e. first char == '-') exists in the *
* given list argc, argv: *
***************************************************************************/
static int GAOptionExists(int argc, char **argv)
{
while (argc--)
if ((*argv++)[0] == '-') return TRUE;
return FALSE;
}
/***************************************************************************
* Routine to print some error messages, for this module: *
***************************************************************************/
void GAPrintErrMsg(int Error)
{
fprintf(stderr, "Error in command line parsing - ");
switch (Error) {
case 0:;
fprintf(stderr, "Undefined error");
break;
case CMD_ERR_NotAnOpt:
fprintf(stderr, "None option Found");
break;
case CMD_ERR_NoSuchOpt:
fprintf(stderr, "Undefined option Found");
break;
case CMD_ERR_WildEmpty:
fprintf(stderr, "Empty input for '!*?' seq.");
break;
case CMD_ERR_NumRead:
fprintf(stderr, "Failed on reading number");
break;
case CMD_ERR_AllSatis:
fprintf(stderr, "Fail to satisfy");
break;
}
fprintf(stderr, " - '%s'.\n", GAErrorToken);
}
/***************************************************************************
* Routine to print correct format of command line allowed: *
***************************************************************************/
void GAPrintHowTo(char *CtrlStr)
{
int i = 0, SpaceFlag;
fprintf(stderr, "Usage: ");
/* Print program name - first word in ctrl. str. (optional): */
while (!(ISSPACE(CtrlStr[i])) && (!ISCTRLCHAR(CtrlStr[i+1])))
fprintf(stderr, "%c", CtrlStr[i++]);
while (i < strlen(CtrlStr)) {
while ((ISSPACE(CtrlStr[i])) && (i < strlen(CtrlStr))) i++;
switch (CtrlStr[i+1]) {
case '%':
fprintf(stderr, " [-%c", CtrlStr[i++]);
i += 2; /* Skip the '%-' or '!- after the char! */
SpaceFlag = TRUE;
while (!ISCTRLCHAR(CtrlStr[i]) && (i < strlen(CtrlStr)) &&
(!ISSPACE(CtrlStr[i])))
if (SpaceFlag) {
if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, " %c", CtrlStr[i-1]);
SpaceFlag = FALSE;
}
else if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, "%c", CtrlStr[i-1]);
while (!ISSPACE(CtrlStr[i]) && (i < strlen(CtrlStr))) {
if (CtrlStr[i] == '*') fprintf(stderr, "...");
i++; /* Skip the rest of it. */
}
fprintf(stderr, "]");
break;
case '!':
fprintf(stderr, " -%c", CtrlStr[i++]);
i += 2; /* Skip the '%-' or '!- after the char! */
SpaceFlag = TRUE;
while (!ISCTRLCHAR(CtrlStr[i]) && (i < strlen(CtrlStr)) &&
(!ISSPACE(CtrlStr[i])))
if (SpaceFlag) {
if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, " %c", CtrlStr[i-1]);
SpaceFlag = FALSE;
}
else if (CtrlStr[i++] == SPACE_CHAR)
fprintf(stderr, " ");
else
fprintf(stderr, "%c", CtrlStr[i-1]);
while (!ISSPACE(CtrlStr[i]) && (i < strlen(CtrlStr))) {
if (CtrlStr[i] == '*') fprintf(stderr, "...");
i++; /* Skip the rest of it. */
}
break;
default: /* Not checked, but must be last one! */
fprintf(stderr, " ");
while (!ISSPACE(CtrlStr[i]) && (i < strlen(CtrlStr)) &&
!ISCTRLCHAR(CtrlStr[i]))
fprintf(stderr, "%c", CtrlStr[i++]);
fprintf(stderr, "\n");
return;
}
}
fprintf(stderr, "\n");
}
#ifdef MYMALLOC
/***************************************************************************
* My Routine to allocate dynamic memory. All program requests must call *
* this routine (no direct call to malloc). Dies if no memory. *
***************************************************************************/
static char *MyMalloc(unsigned size)
{
char *p;
if ((p = (char *) malloc(size)) != NULL) return p;
fprintf(stderr, "Not enough memory, exit.\n");
exit(2);
return NULL; /* Makes warning silent. */
}
#endif /* MYMALLOC */

28
G/LIB/GETARG.H Normal file
View File

@ -0,0 +1,28 @@
/***************************************************************************
* Error numbers as returned by GAGetArg routine: *
* *
* Gershon Elber Mar 88 *
****************************************************************************
* History: *
* 11 Mar 88 - Version 1.0 by Gershon Elber. *
***************************************************************************/
#ifndef GET_ARG_H
#define GET_ARG_H
#define CMD_ERR_NotAnOpt 1 /* None Option found. */
#define CMD_ERR_NoSuchOpt 2 /* Undefined Option Found. */
#define CMD_ERR_WildEmpty 3 /* Empty input for !*? seq. */
#define CMD_ERR_NumRead 4 /* Failed on reading number. */
#define CMD_ERR_AllSatis 5 /* Fail to satisfy (must-'!') option. */
#ifdef USE_VARARGS
int GAGetArgs(int va_alist, ...);
#else
int GAGetArgs(int argc, char **argv, char *CtrlStr, ...);
#endif /* USE_VARARGS */
void GAPrintErrMsg(int Error);
void GAPrintHowTo(char *CtrlStr);
#endif /* GET_ARG_H */

130
G/LIB/GIF_ERR.C Normal file
View File

@ -0,0 +1,130 @@
/*****************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 *
******************************************************************************
* Handle error reporting for the GIF library. *
******************************************************************************
* History: *
* 17 Jun 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/
#include <stdio.h>
#include "gif_lib.h"
#define PROGRAM_NAME "GIF_LIBRARY"
int _GifError = 0;
#ifdef SYSV
static char *VersionStr =
"Gif library module,\t\tGershon Elber\n\
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#else
static char *VersionStr =
PROGRAM_NAME
" IBMPC "
GIF_LIB_VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#endif /* SYSV */
/*****************************************************************************
* Return the last GIF error (0 if none) and reset the error. *
*****************************************************************************/
int GifLastError(void)
{
int i = _GifError;
_GifError = 0;
return i;
}
/*****************************************************************************
* Print the last GIF error to stderr. *
*****************************************************************************/
void PrintGifError(void)
{
char *Err;
switch(_GifError) {
case E_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case E_GIF_ERR_WRITE_FAILED:
Err = "Failed to Write to given file";
break;
case E_GIF_ERR_HAS_SCRN_DSCR:
Err = "Screen Descriptor already been set";
break;
case E_GIF_ERR_HAS_IMAG_DSCR:
Err = "Image Descriptor is still active";
break;
case E_GIF_ERR_NO_COLOR_MAP:
Err = "Neither Global Nor Local color map";
break;
case E_GIF_ERR_DATA_TOO_BIG:
Err = "#Pixels bigger than Width * Height";
break;
case E_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Fail to allocate required memory";
break;
case E_GIF_ERR_DISK_IS_FULL:
Err = "Write failed (disk full?)";
break;
case E_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case E_GIF_ERR_NOT_WRITEABLE:
Err = "Given file was not opened for write";
break;
case D_GIF_ERR_OPEN_FAILED:
Err = "Failed to open given file";
break;
case D_GIF_ERR_READ_FAILED:
Err = "Failed to Read from given file";
break;
case D_GIF_ERR_NOT_GIF_FILE:
Err = "Given file is NOT GIF file";
break;
case D_GIF_ERR_NO_SCRN_DSCR:
Err = "No Screen Descriptor detected";
break;
case D_GIF_ERR_NO_IMAG_DSCR:
Err = "No Image Descriptor detected";
break;
case D_GIF_ERR_NO_COLOR_MAP:
Err = "Neither Global Nor Local color map";
break;
case D_GIF_ERR_WRONG_RECORD:
Err = "Wrong record type detected";
break;
case D_GIF_ERR_DATA_TOO_BIG:
Err = "#Pixels bigger than Width * Height";
break;
case D_GIF_ERR_NOT_ENOUGH_MEM:
Err = "Fail to allocate required memory";
break;
case D_GIF_ERR_CLOSE_FAILED:
Err = "Failed to close given file";
break;
case D_GIF_ERR_NOT_READABLE:
Err = "Given file was not opened for read";
break;
case D_GIF_ERR_IMAGE_DEFECT:
Err = "Image is defective, decoding aborted";
break;
case D_GIF_ERR_EOF_TOO_SOON:
Err = "Image EOF detected, before image complete";
break;
default:
Err = NULL;
break;
}
if (Err != NULL)
fprintf(stderr, "\nGIF-LIB error: %s.\n", Err);
else
fprintf(stderr, "\nGIF-LIB undefined error %d.\n", _GifError);
}

155
G/LIB/GIF_HASH.C Normal file
View File

@ -0,0 +1,155 @@
/*****************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 *
******************************************************************************
* Module to support the following operations: *
* *
* 1. InitHashTable - initialize hash table. *
* 2. ClearHashTable - clear the hash table to an empty state. *
* 2. InsertHashTable - insert one item into data structure. *
* 3. ExistsHashTable - test if item exists in data structure. *
* *
* This module is used to hash the GIF codes during encoding. *
******************************************************************************
* History: *
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/
#ifdef __MSDOS__
#include <io.h>
#include <alloc.h>
#include <sys\stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif /* __MSDOS__ */
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "gif_lib.h"
#include "gif_hash.h"
#define PROGRAM_NAME "GIF_LIBRARY"
/* #define DEBUG_HIT_RATE Debug number of misses per hash Insert/Exists. */
#ifdef DEBUG_HIT_RATE
static long NumberOfTests = 0,
NumberOfMisses = 0;
#endif /* DEBUG_HIT_RATE */
#ifdef SYSV
static char *VersionStr =
"Gif library module,\t\tGershon Elber\n\
(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#else
static char *VersionStr =
PROGRAM_NAME
" IBMPC "
GIF_LIB_VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
#endif /* SYSV */
static int KeyItem(unsigned long Item);
/******************************************************************************
* Initialize HashTable - allocate the memory needed and clear it. *
******************************************************************************/
GifHashTableType *_InitHashTable(void)
{
GifHashTableType *HashTable;
if ((HashTable = (GifHashTableType *) malloc(sizeof(GifHashTableType)))
== NULL)
return NULL;
_ClearHashTable(HashTable);
return HashTable;
}
/******************************************************************************
* Routine to clear the HashTable to an empty state. *
* This part is a little machine depended. Use the commented part otherwise. *
******************************************************************************/
void _ClearHashTable(GifHashTableType *HashTable)
{
memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(long));
}
/******************************************************************************
* Routine to insert a new Item into the HashTable. The data is assumed to be *
* new one. *
******************************************************************************/
void _InsertHashTable(GifHashTableType *HashTable, unsigned long Key, int Code)
{
int HKey = KeyItem(Key);
unsigned long *HTable = HashTable -> HTable;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
HKey = (HKey + 1) & HT_KEY_MASK;
}
HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
}
/******************************************************************************
* Routine to test if given Key exists in HashTable and if so returns its code *
* Returns the Code if key was found, -1 if not. *
******************************************************************************/
int _ExistsHashTable(GifHashTableType *HashTable, unsigned long Key)
{
int HKey = KeyItem(Key);
unsigned long *HTable = HashTable -> HTable, HTKey;
#ifdef DEBUG_HIT_RATE
NumberOfTests++;
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
#ifdef DEBUG_HIT_RATE
NumberOfMisses++;
#endif /* DEBUG_HIT_RATE */
if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
HKey = (HKey + 1) & HT_KEY_MASK;
}
return -1;
}
/******************************************************************************
* Routine to generate an HKey for the hashtable out of the given unique key. *
* The given Key is assumed to be 20 bits as follows: lower 8 bits are the *
* new postfix character, while the upper 12 bits are the prefix code. *
* Because the average hit ratio is only 2 (2 hash references per entry), *
* evaluating more complex keys (such as twin prime keys) does not worth it! *
******************************************************************************/
static int KeyItem(unsigned long Item)
{
return ((Item >> 12) ^ Item) & HT_KEY_MASK;
}
#ifdef DEBUG_HIT_RATE
/******************************************************************************
* Debugging routine to print the hit ratio - number of times the hash table *
* was tested per operation. This routine was used to test the KeyItem routine *
******************************************************************************/
void HashTablePrintHitRatio(void)
{
printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n",
NumberOfMisses, NumberOfTests,
NumberOfMisses * 100 / NumberOfTests);
}
#endif /* DEBUG_HIT_RATE */

31
G/LIB/GIF_HASH.H Normal file
View File

@ -0,0 +1,31 @@
/******************************************************************************
* Declarations, global to other of the GIF-HASH.C module. *
* *
* Written by Gershon Elber, Jun 1989 *
*******************************************************************************
* History: *
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
******************************************************************************/
#define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK 0x1FFF /* 13bits keys */
#define HT_KEY_NUM_BITS 13 /* 13bits keys */
#define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */
#define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
/* The 32 bits of the long are divided into two parts for the key & code: */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */
#define HT_GET_KEY(l) (l >> 12)
#define HT_GET_CODE(l) (l & 0x0FFF)
#define HT_PUT_KEY(l) (l << 12)
#define HT_PUT_CODE(l) (l & 0x0FFF)
typedef struct GifHashTableType {
unsigned long HTable[HT_SIZE];
} GifHashTableType;
GifHashTableType *_InitHashTable(void);
void _ClearHashTable(GifHashTableType *HashTable);
void _InsertHashTable(GifHashTableType *HashTable, unsigned long Key, int Code);
int _ExistsHashTable(GifHashTableType *HashTable, unsigned long Key); G

178
G/LIB/GIF_LIB.H Normal file
View File

@ -0,0 +1,178 @@
/******************************************************************************
* In order to make life a little bit easier when using the GIF file format, *
* this library was written, and which does all the dirty work... *
* *
* Written by Gershon Elber, Jun. 1989 *
*******************************************************************************
* History: *
* 14 Jun 89 - Version 1.0 by Gershon Elber. *
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
******************************************************************************/
#ifndef GIF_LIB_H
#define GIF_LIB_H
#define GIF_LIB_VERSION " Version 1.2, "
#define GIF_ERROR 0
#define GIF_OK 1
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char * GifRowType;
typedef unsigned char GifByteType;
#define GIF_MESSAGE(Msg) fprintf(stderr, "\n%s: %s\n", PROGRAM_NAME, Msg)
#define GIF_EXIT(Msg) { GIF_MESSAGE(Msg); exit(-3); }
#ifdef SYSV
#define VoidPtr char *
#else
#define VoidPtr void *
#endif /* SYSV */
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
/* Note entries prefixed with S are of Screen information, while entries */
/* prefixed with I are of the current defined Image. */
typedef struct GifFileType {
int SWidth, SHeight, /* Screen dimensions. */
SColorResolution, SBitsPerPixel, /* How many colors can we generate? */
SBackGroundColor, /* I hope you understand this one... */
ILeft, ITop, IWidth, IHeight, /* Current image dimensions. */
IInterlace, /* Sequential/Interlaced lines. */
IBitsPerPixel; /* How many colors this image has? */
GifColorType *SColorMap, *IColorMap; /* NULL if not exists. */
VoidPtr Private; /* The regular user should not mess with this one! */
} GifFileType;
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* DumpScreen2Gif routine constants identify type of window/screen to dump. */
/* Note all values below 1000 are reserved for the IBMPC different display */
/* devices (it has many!) and are compatible with the numbering TC2.0 */
/* (Turbo C 2.0 compiler for IBM PC) gives to these devices. */
typedef enum {
GIF_DUMP_SGI_WINDOW = 1000,
GIF_DUMP_X_WINDOW = 1001
} GifScreenDumpType;
/******************************************************************************
* O.k. here are the routines one can access in order to encode GIF file: *
* (GIF_LIB file EGIF_LIB.C). *
******************************************************************************/
GifFileType *EGifOpenFileName(char *GifFileName, int GifTestExistance);
GifFileType *EGifOpenFileHandle(int GifFileHandle);
void EGifSetGifVersion(char *Version);
int EGifPutScreenDesc(GifFileType *GifFile,
int GifWidth, int GifHeight, int GifColorRes, int GifBackGround,
int GifBitsPerPixel, GifColorType *GifColorMap);
int EGifPutImageDesc(GifFileType *GifFile,
int GifLeft, int GifTop, int Width, int GifHeight, int GifInterlace,
int GifBitsPerPixel, GifColorType *GifColorMap);
int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int EGifPutPixel(GifFileType *GifFile, GifPixelType GifPixel);
int EGifPutComment(GifFileType *GifFile, char *GifComment);
int EGifPutExtension(GifFileType *GifFile, int GifExtCode, int GifExtLen,
VoidPtr GifExtension);
int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
GifByteType *GifCodeBlock);
int EGifPutCodeNext(GifFileType *GifFile, GifByteType *GifCodeBlock);
int EGifCloseFile(GifFileType *GifFile);
#define E_GIF_ERR_OPEN_FAILED 1 /* And EGif possible errors. */
#define E_GIF_ERR_WRITE_FAILED 2
#define E_GIF_ERR_HAS_SCRN_DSCR 3
#define E_GIF_ERR_HAS_IMAG_DSCR 4
#define E_GIF_ERR_NO_COLOR_MAP 5
#define E_GIF_ERR_DATA_TOO_BIG 6
#define E_GIF_ERR_NOT_ENOUGH_MEM 7
#define E_GIF_ERR_DISK_IS_FULL 8
#define E_GIF_ERR_CLOSE_FAILED 9
#define E_GIF_ERR_NOT_WRITEABLE 10
/******************************************************************************
* O.k. here are the routines one can access in order to decode GIF file: *
* (GIF_LIB file DGIF_LIB.C). *
******************************************************************************/
GifFileType *DGifOpenFileName(char *GifFileName);
GifFileType *DGifOpenFileHandle(int GifFileHandle);
int DGifGetScreenDesc(GifFileType *GifFile);
int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
int DGifGetImageDesc(GifFileType *GifFile);
int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
int DGifGetComment(GifFileType *GifFile, char *GifComment);
int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
GifByteType **GifExtension);
int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
GifByteType **GifCodeBlock);
int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
int DGifCloseFile(GifFileType *GifFile);
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/******************************************************************************
* O.k. here are the routines from GIF_LIB file QUANTIZE.C. *
******************************************************************************/
int QuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize,
GifByteType *RedInput, GifByteType *GreenInput, GifByteType *BlueInput,
GifByteType *OutputBuffer, GifColorType *OutputColorMap);
/******************************************************************************
* O.k. here are the routines from GIF_LIB file QPRINTF.C. *
******************************************************************************/
extern int GifQuitePrint;
#ifdef USE_VARARGS
void GifQprintf();
#else
void GifQprintf(char *Format, ...);
#endif /* USE_VARARGS */
/******************************************************************************
* O.k. here are the routines from GIF_LIB file GIF_ERR.C. *
******************************************************************************/
void PrintGifError(void);
int GifLastError(void);
/******************************************************************************
* O.k. here are the routines from GIF_LIB file DEV2GIF.C. *
******************************************************************************/
int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
int ReqGraphMode2,
int ReqGraphMode3);
#endif /* GIF_LIB_H */

BIN
G/LIB/GIF_LIBC.LIB Normal file

Binary file not shown.

39
G/LIB/GIF_LIBC.LST Normal file
View File

@ -0,0 +1,39 @@
Publics by module
DEV2GIF size = 1630
_DumpScreen2Gif
DGIF_LIB size = 4640
_DGifCloseFile _DGifGetCode
_DGifGetCodeNext _DGifGetExtension
_DGifGetExtensionNext _DGifGetImageDesc
_DGifGetLZCodes _DGifGetLine
_DGifGetPixel _DGifGetRecordType
_DGifGetScreenDesc _DGifOpenFileHandle
_DGifOpenFileName
EGIF_LIB size = 4246
_EGifCloseFile _EGifOpenFileHandle
_EGifOpenFileName _EGifPutCode
_EGifPutCodeNext _EGifPutComment
_EGifPutExtension _EGifPutImageDesc
_EGifPutLine _EGifPutPixel
_EGifPutScreenDesc _EGifSetGifVersion
GETARG size = 4707
_GAGetArgs _GAPrintErrMsg
_GAPrintHowTo
GIF_ERR size = 1235
_GifLastError _PrintGifError
__GifError
GIF_HASH size = 496
__ClearHashTable __ExistsHashTable
__InitHashTable __InsertHashTable
QPRINTF size = 70
_GifQprintf _GifQuitePrint
QUANTIZE size = 3217
_QuantizeBuffer

BIN
G/LIB/GIF_LIBH.LIB Normal file

Binary file not shown.

39
G/LIB/GIF_LIBH.LST Normal file
View File

@ -0,0 +1,39 @@
Publics by module
DEV2GIF size = 1713
_DumpScreen2Gif
DGIF_LIB size = 5155
_DGifCloseFile _DGifGetCode
_DGifGetCodeNext _DGifGetExtension
_DGifGetExtensionNext _DGifGetImageDesc
_DGifGetLZCodes _DGifGetLine
_DGifGetPixel _DGifGetRecordType
_DGifGetScreenDesc _DGifOpenFileHandle
_DGifOpenFileName
EGIF_LIB size = 4751
_EGifCloseFile _EGifOpenFileHandle
_EGifOpenFileName _EGifPutCode
_EGifPutCodeNext _EGifPutComment
_EGifPutExtension _EGifPutImageDesc
_EGifPutLine _EGifPutPixel
_EGifPutScreenDesc _EGifSetGifVersion
GETARG size = 5054
_GAGetArgs _GAPrintErrMsg
_GAPrintHowTo
GIF_ERR size = 1260
_GifLastError _PrintGifError
__GifError
GIF_HASH size = 551
__ClearHashTable __ExistsHashTable
__InitHashTable __InsertHashTable
QPRINTF size = 84
_GifQprintf _GifQuitePrint
QUANTIZE size = 3287
_QuantizeBuffer

BIN
G/LIB/GIF_LIBL.LIB Normal file

Binary file not shown.

39
G/LIB/GIF_LIBL.LST Normal file
View File

@ -0,0 +1,39 @@
Publics by module
DEV2GIF size = 1680
_DumpScreen2Gif
DGIF_LIB size = 4766
_DGifCloseFile _DGifGetCode
_DGifGetCodeNext _DGifGetExtension
_DGifGetExtensionNext _DGifGetImageDesc
_DGifGetLZCodes _DGifGetLine
_DGifGetPixel _DGifGetRecordType
_DGifGetScreenDesc _DGifOpenFileHandle
_DGifOpenFileName
EGIF_LIB size = 4388
_EGifCloseFile _EGifOpenFileHandle
_EGifOpenFileName _EGifPutCode
_EGifPutCodeNext _EGifPutComment
_EGifPutExtension _EGifPutImageDesc
_EGifPutLine _EGifPutPixel
_EGifPutScreenDesc _EGifSetGifVersion
GETARG size = 4879
_GAGetArgs _GAPrintErrMsg
_GAPrintHowTo
GIF_ERR size = 1239
_GifLastError _PrintGifError
__GifError
GIF_HASH size = 514
__ClearHashTable __ExistsHashTable
__InitHashTable __InsertHashTable
QPRINTF size = 74
_GifQprintf _GifQuitePrint
QUANTIZE size = 3253
_QuantizeBuffer

BIN
G/LIB/GIF_LIBM.LIB Normal file

Binary file not shown.

39
G/LIB/GIF_LIBM.LST Normal file
View File

@ -0,0 +1,39 @@
Publics by module
DEV2GIF size = 1576
_DumpScreen2Gif
DGIF_LIB size = 3718
_DGifCloseFile _DGifGetCode
_DGifGetCodeNext _DGifGetExtension
_DGifGetExtensionNext _DGifGetImageDesc
_DGifGetLZCodes _DGifGetLine
_DGifGetPixel _DGifGetRecordType
_DGifGetScreenDesc _DGifOpenFileHandle
_DGifOpenFileName
EGIF_LIB size = 3357
_EGifCloseFile _EGifOpenFileHandle
_EGifOpenFileName _EGifPutCode
_EGifPutCodeNext _EGifPutComment
_EGifPutExtension _EGifPutImageDesc
_EGifPutLine _EGifPutPixel
_EGifPutScreenDesc _EGifSetGifVersion
GETARG size = 3871
_GAGetArgs _GAPrintErrMsg
_GAPrintHowTo
GIF_ERR size = 1066
_GifLastError _PrintGifError
__GifError
GIF_HASH size = 456
__ClearHashTable __ExistsHashTable
__InitHashTable __InsertHashTable
QPRINTF size = 62
_GifQprintf _GifQuitePrint
QUANTIZE size = 2876
_QuantizeBuffer

BIN
G/LIB/GIF_LIBS.LIB Normal file

Binary file not shown.

39
G/LIB/GIF_LIBS.LST Normal file
View File

@ -0,0 +1,39 @@
Publics by module
DEV2GIF size = 1526
_DumpScreen2Gif
DGIF_LIB size = 3595
_DGifCloseFile _DGifGetCode
_DGifGetCodeNext _DGifGetExtension
_DGifGetExtensionNext _DGifGetImageDesc
_DGifGetLZCodes _DGifGetLine
_DGifGetPixel _DGifGetRecordType
_DGifGetScreenDesc _DGifOpenFileHandle
_DGifOpenFileName
EGIF_LIB size = 3214
_EGifCloseFile _EGifOpenFileHandle
_EGifOpenFileName _EGifPutCode
_EGifPutCodeNext _EGifPutComment
_EGifPutExtension _EGifPutImageDesc
_EGifPutLine _EGifPutPixel
_EGifPutScreenDesc _EGifSetGifVersion
GETARG size = 3701
_GAGetArgs _GAPrintErrMsg
_GAPrintHowTo
GIF_ERR size = 1062
_GifLastError _PrintGifError
__GifError
GIF_HASH size = 438
__ClearHashTable __ExistsHashTable
__InitHashTable __InsertHashTable
QPRINTF size = 58
_GifQprintf _GifQuitePrint
QUANTIZE size = 2840
_QuantizeBuffer

63
G/LIB/MAKEFILE.TC Normal file
View File

@ -0,0 +1,63 @@
#
# This is the make file for the lib subdirectory of the GIF library
# In order to run it tcc is assumed to be available, in addition to
# tlib and obviously borland make.
#
# Usage: "make [-DMDL=model]" where model can be l (large) or c (compact) etc.
# Note the MDL is optional with large model as default.
#
# Gershon Elber, Jun 1989
#
# Works only on TC++ 1.0 make and up - swap out make before invoking command.
.SWAP
# Your C compiler
CC = d:\program\borlandc\bin\bcc
# MDL set?
!if !$d(MDL)
MDL=l
!endif
# Where all the include files are:
INC = -I.
CFLAGS = -m$(MDL) -a- -f- -G -O -r -c -d -w -v- -y- -k- -N-
DEST = ..\bin
OBJS = dev2gif.obj egif_lib.obj dgif_lib.obj gif_hash.obj \
qprintf.obj gif_err.obj getarg.obj quantize.obj
# Show me better way if you know one to prepare this line for TLIB:
POBJS = +dev2gif.obj +egif_lib.obj +dgif_lib.obj +gif_hash.obj \
+qprintf.obj +gif_err.obj +getarg.obj +quantize.obj
# The {$< } is also new to TC++ 1.0 make - remove the { } pair if your make
# choke on them (the { } signals batch mode that combines few operation at the
# same time - very nice feature!).
.c.obj:
$(CC) $(INC) $(CFLAGS) {$< }
gif_libl.lib: $(OBJS)
del gif_lib$(MDL).lib
tlib gif_lib$(MDL).lib @&&!
$(POBJS), gif_lib$(MDL).lst
!
copy gif_lib$(MDL).lib $(DEST)
dev2gif.obj: gif_lib.h
egif_lib.obj: gif_lib.h gif_hash.h
dgif_lib.obj: gif_lib.h gif_hash.h
gif_hash.obj: gif_lib.h gif_hash.h
qprintf.obj: gif_lib.h
gif_err.obj: gif_lib.h
getarg.obj: getarg.h

Some files were not shown because too many files have changed in this diff Show More