First commit ~0,10
This commit is contained in:
commit
37dffcdec3
781
BDATOS/BDATOS.CPP
Normal file
781
BDATOS/BDATOS.CPP
Normal 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
BIN
BDATOS/BDATOS.DSK
Normal file
Binary file not shown.
BIN
BDATOS/BDATOS.EXE
Normal file
BIN
BDATOS/BDATOS.EXE
Normal file
Binary file not shown.
147
BDATOS/BDATOS.HH
Normal file
147
BDATOS/BDATOS.HH
Normal file
@ -0,0 +1,147 @@
|
||||
/**************************************************************************\
|
||||
| |
|
||||
| Clase para el tratamiento de Bases de Datos |
|
||||
| |
|
||||
| Jos‚ David Guill‚n 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
BIN
BDATOS/BDATOS.PRJ
Normal file
Binary file not shown.
BIN
BDATOS/BDATOS.TFA
Normal file
BIN
BDATOS/BDATOS.TFA
Normal file
Binary file not shown.
297
BDATOS/PRUEBA.CPP
Normal file
297
BDATOS/PRUEBA.CPP
Normal 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
2
G/BACKUP.BAT
Normal 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
300
G/BIN/BGI.CPP
Normal 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,®);
|
||||
}
|
BIN
G/BIN/DISCO.GIF
Normal file
BIN
G/BIN/DISCO.GIF
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
3
G/BIN/DUMMY
Normal file
3
G/BIN/DUMMY
Normal 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
BIN
G/BIN/GIF.DSK
Normal file
Binary file not shown.
BIN
G/BIN/GIF.EXE
Normal file
BIN
G/BIN/GIF.EXE
Normal file
Binary file not shown.
BIN
G/BIN/GIF.PRJ
Normal file
BIN
G/BIN/GIF.PRJ
Normal file
Binary file not shown.
207
G/BIN/GIF_LIB.H
Normal file
207
G/BIN/GIF_LIB.H
Normal 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
BIN
G/BIN/GIF_LIBC.LIB
Normal file
Binary file not shown.
BIN
G/BIN/GIF_LIBH.LIB
Normal file
BIN
G/BIN/GIF_LIBH.LIB
Normal file
Binary file not shown.
BIN
G/BIN/GIF_LIBL.LIB
Normal file
BIN
G/BIN/GIF_LIBL.LIB
Normal file
Binary file not shown.
BIN
G/BIN/GIF_LIBM.LIB
Normal file
BIN
G/BIN/GIF_LIBM.LIB
Normal file
Binary file not shown.
BIN
G/BIN/GIF_LIBS.LIB
Normal file
BIN
G/BIN/GIF_LIBS.LIB
Normal file
Binary file not shown.
BIN
G/BIN/GRAPHBGI.LIB
Normal file
BIN
G/BIN/GRAPHBGI.LIB
Normal file
Binary file not shown.
106
G/COMPILE.ME
Normal file
106
G/COMPILE.ME
Normal 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
22
G/DOC/GENERAL.DOC
Normal 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
88
G/DOC/GIF2BGI.DOC
Normal 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
62
G/DOC/GIF2EPSN.DOC
Normal 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
82
G/DOC/GIF2HERC.DOC
Normal 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
30
G/DOC/GIF2IRIS.DOC
Normal 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
42
G/DOC/GIF2PS.DOC
Normal 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
36
G/DOC/GIF2RGB.DOC
Normal 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
33
G/DOC/GIF2RLE.DOC
Normal 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
37
G/DOC/GIF2X11.DOC
Normal 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
35
G/DOC/GIFASM.DOC
Normal 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
53
G/DOC/GIFBG.DOC
Normal 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
40
G/DOC/GIFCLIP.DOC
Normal 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
38
G/DOC/GIFCLRMP.DOC
Normal 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
34
G/DOC/GIFCOMB.DOC
Normal 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
26
G/DOC/GIFFIX.DOC
Normal 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
32
G/DOC/GIFFLIP.DOC
Normal 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
43
G/DOC/GIFHISTO.DOC
Normal 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
28
G/DOC/GIFINTER.DOC
Normal 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
32
G/DOC/GIFINTO.DOC
Normal 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
33
G/DOC/GIFPOS.DOC
Normal 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
40
G/DOC/GIFROTAT.DOC
Normal 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
33
G/DOC/GIFRSIZE.DOC
Normal 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
41
G/DOC/GIFTEXT.DOC
Normal 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
32
G/DOC/GIFWEDGE.DOC
Normal 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
477
G/DOC/GIF_LIB.DOC
Normal 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
125
G/DOC/LIBERROR.DOC
Normal 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
36
G/DOC/RAW2GIF.DOC
Normal 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
39
G/DOC/RGB2GIF.DOC
Normal 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
36
G/DOC/RLE2GIF.DOC
Normal 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
48
G/DOC/TEXT2GIF.DOC
Normal 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
36
G/DOS2UNIX
Normal 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
BIN
G/GIF/BGI.EXE
Normal file
Binary file not shown.
BIN
G/GIF/CHERYL.GIF
Normal file
BIN
G/GIF/CHERYL.GIF
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
G/GIF/DISCO.GIF
Normal file
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
BIN
G/GIF/GIF.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIF2BGI.EXE
Normal file
BIN
G/GIF/GIF2BGI.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIF2EPSN.EXE
Normal file
BIN
G/GIF/GIF2EPSN.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIF2HERC.EXE
Normal file
BIN
G/GIF/GIF2HERC.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIF2PS.EXE
Normal file
BIN
G/GIF/GIF2PS.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIF2RGB.EXE
Normal file
BIN
G/GIF/GIF2RGB.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFCLRMP.EXE
Normal file
BIN
G/GIF/GIFCLRMP.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFCOMB.EXE
Normal file
BIN
G/GIF/GIFCOMB.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFFIX.EXE
Normal file
BIN
G/GIF/GIFFIX.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFFLIP.EXE
Normal file
BIN
G/GIF/GIFFLIP.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFHISTO.EXE
Normal file
BIN
G/GIF/GIFHISTO.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFINTER.EXE
Normal file
BIN
G/GIF/GIFINTER.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFINTO.EXE
Normal file
BIN
G/GIF/GIFINTO.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFPOS.EXE
Normal file
BIN
G/GIF/GIFPOS.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFROTAT.EXE
Normal file
BIN
G/GIF/GIFROTAT.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFRSIZE.EXE
Normal file
BIN
G/GIF/GIFRSIZE.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFTEXT.EXE
Normal file
BIN
G/GIF/GIFTEXT.EXE
Normal file
Binary file not shown.
BIN
G/GIF/GIFWEDGE.EXE
Normal file
BIN
G/GIF/GIFWEDGE.EXE
Normal file
Binary file not shown.
BIN
G/GIF/HERC2GIF.EXE
Normal file
BIN
G/GIF/HERC2GIF.EXE
Normal file
Binary file not shown.
BIN
G/GIF/PORSCHE.GIF
Normal file
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
BIN
G/GIF/RAW2GIF.EXE
Normal file
Binary file not shown.
BIN
G/GIF/RGB2GIF.EXE
Normal file
BIN
G/GIF/RGB2GIF.EXE
Normal file
Binary file not shown.
BIN
G/GIF/SOLID2.GIF
Normal file
BIN
G/GIF/SOLID2.GIF
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
G/GIF/TEXT2GIF.EXE
Normal file
BIN
G/GIF/TEXT2GIF.EXE
Normal file
Binary file not shown.
512
G/LIB/DEV2GIF.C
Normal file
512
G/LIB/DEV2GIF.C
Normal 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
837
G/LIB/DGIF_LIB.C
Normal 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
774
G/LIB/EGIF_LIB.C
Normal 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
632
G/LIB/GETARG.C
Normal 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
28
G/LIB/GETARG.H
Normal 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
130
G/LIB/GIF_ERR.C
Normal 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
155
G/LIB/GIF_HASH.C
Normal 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
31
G/LIB/GIF_HASH.H
Normal 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
178
G/LIB/GIF_LIB.H
Normal 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
BIN
G/LIB/GIF_LIBC.LIB
Normal file
Binary file not shown.
39
G/LIB/GIF_LIBC.LST
Normal file
39
G/LIB/GIF_LIBC.LST
Normal 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
BIN
G/LIB/GIF_LIBH.LIB
Normal file
Binary file not shown.
39
G/LIB/GIF_LIBH.LST
Normal file
39
G/LIB/GIF_LIBH.LST
Normal 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
BIN
G/LIB/GIF_LIBL.LIB
Normal file
Binary file not shown.
39
G/LIB/GIF_LIBL.LST
Normal file
39
G/LIB/GIF_LIBL.LST
Normal 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
BIN
G/LIB/GIF_LIBM.LIB
Normal file
Binary file not shown.
39
G/LIB/GIF_LIBM.LST
Normal file
39
G/LIB/GIF_LIBM.LST
Normal 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
BIN
G/LIB/GIF_LIBS.LIB
Normal file
Binary file not shown.
39
G/LIB/GIF_LIBS.LST
Normal file
39
G/LIB/GIF_LIBS.LST
Normal 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
63
G/LIB/MAKEFILE.TC
Normal 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
Loading…
x
Reference in New Issue
Block a user