commit 37dffcdec3c859e215f060e9c42f4415ea40fa0e Author: jdg Date: Wed Sep 8 21:26:43 2021 +0200 First commit ~0,10 diff --git a/BDATOS/BDATOS.CPP b/BDATOS/BDATOS.CPP new file mode 100644 index 0000000..1c2f39f --- /dev/null +++ b/BDATOS/BDATOS.CPP @@ -0,0 +1,781 @@ +#include +#include +#include +#include + +#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 nmero 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 nmero de registros total, total del la base. | +| | +| | +| Entradas: (ninguna) | +| | +| Salidas: numero de registros | +| | + \**************************************************************************/ +long BDatos::NRegTotal(void) +{ + return BDatosHeader.NRegTotal; +} + + /**************************************************************************\ +| | +| RegActual | +| | +| Descripcion: | +| Obtiene el nmero 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 posicin '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 posicin '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 posicin 'pos' por arriba o abajo | +| | +| | +| Entradas: puntero a los datos a insertar, posicin, 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 posicin 'pos' | +| | +| | +| Entradas: posicin 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 pequeo. | +| | +| | +| 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 direccin 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 direccin 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 posicin. + 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 direccin 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 posicin." ); + break; + case 0x05: + strcpy( cError, "No hay base de datos en uso..." ); + break; + case 0x06: + strcpy( cError, "Tamaos de estructuras no coinciden" ); + break; + case 0x07: + strcpy( cError, "Memoria insuficiente. Operacin cancelada" ); + break; + case 0x08: + strcpy( cError, "Acceso de operacion no permitida." ); + break; + } + +} + + + /**************************************************************************\ +| | +| SortReg | +| | +| Descripcion: | +| Ordena la base de datos segn especifique el usuario en su | +| funcin fcmp... | +| | +| Entradas: /**************************************************************\ | +| | fcmp || +| | || +| | Descripcion: || +| | funcin de entrada a SortReg, debe ser realizada || +| | por el usuario y debe ceirse a sus parmetros.. || +| | || +| | 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 | +| Tamao 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 ); + +} \ No newline at end of file diff --git a/BDATOS/BDATOS.DSK b/BDATOS/BDATOS.DSK new file mode 100644 index 0000000..e1214c5 Binary files /dev/null and b/BDATOS/BDATOS.DSK differ diff --git a/BDATOS/BDATOS.EXE b/BDATOS/BDATOS.EXE new file mode 100644 index 0000000..4763e66 Binary files /dev/null and b/BDATOS/BDATOS.EXE differ diff --git a/BDATOS/BDATOS.HH b/BDATOS/BDATOS.HH new file mode 100644 index 0000000..8dfbdb9 --- /dev/null +++ b/BDATOS/BDATOS.HH @@ -0,0 +1,147 @@ + /**************************************************************************\ +| | +| Clase para el tratamiento de Bases de Datos | +| | +| Jos David Guilln 1996 (c) | +| | +| | + \**************************************************************************/ + + +#if !defined(__BDatos_HH) +#define __BDatos_HH + +#include + +#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 pequeo + + // 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 ordenacin + 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 * +*/ + + diff --git a/BDATOS/BDATOS.PRJ b/BDATOS/BDATOS.PRJ new file mode 100644 index 0000000..9aeef56 Binary files /dev/null and b/BDATOS/BDATOS.PRJ differ diff --git a/BDATOS/BDATOS.TFA b/BDATOS/BDATOS.TFA new file mode 100644 index 0000000..8f45687 Binary files /dev/null and b/BDATOS/BDATOS.TFA differ diff --git a/BDATOS/PRUEBA.CPP b/BDATOS/PRUEBA.CPP new file mode 100644 index 0000000..8fd36ec --- /dev/null +++ b/BDATOS/PRUEBA.CPP @@ -0,0 +1,297 @@ + /*************************************************************************\ +| | +| Programa para probar el buen funcionamiento de la libreria BDatos .(JD) | +| | +| 12.03.96 | + \*************************************************************************/ +#include +#include +#include +#include + +#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, condicin 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 nombre, ((DummyStruct *)B) -> nombre ); +} + diff --git a/G/BACKUP.BAT b/G/BACKUP.BAT new file mode 100644 index 0000000..232f8b9 --- /dev/null +++ b/G/BACKUP.BAT @@ -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 *.* + \ No newline at end of file diff --git a/G/BIN/BGI.CPP b/G/BIN/BGI.CPP new file mode 100644 index 0000000..e22dcb3 --- /dev/null +++ b/G/BIN/BGI.CPP @@ -0,0 +1,300 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 posicin de inicio fsica *| +|* decodifica y muestra est en pantalla... *| +|* *| +|* Entradas: *| +|* Nombre de Archivo, Posiciones iniciales X, Y *| +|* Salidas: *| +|* OK *| +|* Cdigos 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,®); +} diff --git a/G/BIN/DISCO.GIF b/G/BIN/DISCO.GIF new file mode 100644 index 0000000..f3d6b76 Binary files /dev/null and b/G/BIN/DISCO.GIF differ diff --git a/G/BIN/DUMMY b/G/BIN/DUMMY new file mode 100644 index 0000000..9dfa6ca --- /dev/null +++ b/G/BIN/DUMMY @@ -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. \ No newline at end of file diff --git a/G/BIN/GIF.DSK b/G/BIN/GIF.DSK new file mode 100644 index 0000000..999f258 Binary files /dev/null and b/G/BIN/GIF.DSK differ diff --git a/G/BIN/GIF.EXE b/G/BIN/GIF.EXE new file mode 100644 index 0000000..cab0bf5 Binary files /dev/null and b/G/BIN/GIF.EXE differ diff --git a/G/BIN/GIF.PRJ b/G/BIN/GIF.PRJ new file mode 100644 index 0000000..533e691 Binary files /dev/null and b/G/BIN/GIF.PRJ differ diff --git a/G/BIN/GIF_LIB.H b/G/BIN/GIF_LIB.H new file mode 100644 index 0000000..e390190 --- /dev/null +++ b/G/BIN/GIF_LIB.H @@ -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 */ diff --git a/G/BIN/GIF_LIBC.LIB b/G/BIN/GIF_LIBC.LIB new file mode 100644 index 0000000..3f66058 Binary files /dev/null and b/G/BIN/GIF_LIBC.LIB differ diff --git a/G/BIN/GIF_LIBH.LIB b/G/BIN/GIF_LIBH.LIB new file mode 100644 index 0000000..39dd408 Binary files /dev/null and b/G/BIN/GIF_LIBH.LIB differ diff --git a/G/BIN/GIF_LIBL.LIB b/G/BIN/GIF_LIBL.LIB new file mode 100644 index 0000000..9839f37 Binary files /dev/null and b/G/BIN/GIF_LIBL.LIB differ diff --git a/G/BIN/GIF_LIBM.LIB b/G/BIN/GIF_LIBM.LIB new file mode 100644 index 0000000..20dd32a Binary files /dev/null and b/G/BIN/GIF_LIBM.LIB differ diff --git a/G/BIN/GIF_LIBS.LIB b/G/BIN/GIF_LIBS.LIB new file mode 100644 index 0000000..1612f3d Binary files /dev/null and b/G/BIN/GIF_LIBS.LIB differ diff --git a/G/BIN/GRAPHBGI.LIB b/G/BIN/GRAPHBGI.LIB new file mode 100644 index 0000000..3cd56cd Binary files /dev/null and b/G/BIN/GRAPHBGI.LIB differ diff --git a/G/COMPILE.ME b/G/COMPILE.ME new file mode 100644 index 0000000..3cf80b4 --- /dev/null +++ b/G/COMPILE.ME @@ -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 diff --git a/G/DOC/GENERAL.DOC b/G/DOC/GENERAL.DOC new file mode 100644 index 0000000..600302a --- /dev/null +++ b/G/DOC/GENERAL.DOC @@ -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. diff --git a/G/DOC/GIF2BGI.DOC b/G/DOC/GIF2BGI.DOC new file mode 100644 index 0000000..0efd112 --- /dev/null +++ b/G/DOC/GIF2BGI.DOC @@ -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? \ No newline at end of file diff --git a/G/DOC/GIF2EPSN.DOC b/G/DOC/GIF2EPSN.DOC new file mode 100644 index 0000000..67883c7 --- /dev/null +++ b/G/DOC/GIF2EPSN.DOC @@ -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... diff --git a/G/DOC/GIF2HERC.DOC b/G/DOC/GIF2HERC.DOC new file mode 100644 index 0000000..3819f1d --- /dev/null +++ b/G/DOC/GIF2HERC.DOC @@ -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. diff --git a/G/DOC/GIF2IRIS.DOC b/G/DOC/GIF2IRIS.DOC new file mode 100644 index 0000000..aeb3b3a --- /dev/null +++ b/G/DOC/GIF2IRIS.DOC @@ -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. + diff --git a/G/DOC/GIF2PS.DOC b/G/DOC/GIF2PS.DOC new file mode 100644 index 0000000..917f63e --- /dev/null +++ b/G/DOC/GIF2PS.DOC @@ -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. + diff --git a/G/DOC/GIF2RGB.DOC b/G/DOC/GIF2RGB.DOC new file mode 100644 index 0000000..b74e721 --- /dev/null +++ b/G/DOC/GIF2RGB.DOC @@ -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: +------ diff --git a/G/DOC/GIF2RLE.DOC b/G/DOC/GIF2RLE.DOC new file mode 100644 index 0000000..12d5ff5 --- /dev/null +++ b/G/DOC/GIF2RLE.DOC @@ -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... diff --git a/G/DOC/GIF2X11.DOC b/G/DOC/GIF2X11.DOC new file mode 100644 index 0000000..5071908 --- /dev/null +++ b/G/DOC/GIF2X11.DOC @@ -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. + diff --git a/G/DOC/GIFASM.DOC b/G/DOC/GIFASM.DOC new file mode 100644 index 0000000..5da2b38 --- /dev/null +++ b/G/DOC/GIFASM.DOC @@ -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. diff --git a/G/DOC/GIFBG.DOC b/G/DOC/GIFBG.DOC new file mode 100644 index 0000000..7f630df --- /dev/null +++ b/G/DOC/GIFBG.DOC @@ -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. + \ No newline at end of file diff --git a/G/DOC/GIFCLIP.DOC b/G/DOC/GIFCLIP.DOC new file mode 100644 index 0000000..6642a15 --- /dev/null +++ b/G/DOC/GIFCLIP.DOC @@ -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. diff --git a/G/DOC/GIFCLRMP.DOC b/G/DOC/GIFCLRMP.DOC new file mode 100644 index 0000000..d618fd9 --- /dev/null +++ b/G/DOC/GIFCLRMP.DOC @@ -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. diff --git a/G/DOC/GIFCOMB.DOC b/G/DOC/GIFCOMB.DOC new file mode 100644 index 0000000..a08c16c --- /dev/null +++ b/G/DOC/GIFCOMB.DOC @@ -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. diff --git a/G/DOC/GIFFIX.DOC b/G/DOC/GIFFIX.DOC new file mode 100644 index 0000000..7925226 --- /dev/null +++ b/G/DOC/GIFFIX.DOC @@ -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. diff --git a/G/DOC/GIFFLIP.DOC b/G/DOC/GIFFLIP.DOC new file mode 100644 index 0000000..96abf20 --- /dev/null +++ b/G/DOC/GIFFLIP.DOC @@ -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. diff --git a/G/DOC/GIFHISTO.DOC b/G/DOC/GIFHISTO.DOC new file mode 100644 index 0000000..eea2799 --- /dev/null +++ b/G/DOC/GIFHISTO.DOC @@ -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. diff --git a/G/DOC/GIFINTER.DOC b/G/DOC/GIFINTER.DOC new file mode 100644 index 0000000..dbfee69 --- /dev/null +++ b/G/DOC/GIFINTER.DOC @@ -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. + diff --git a/G/DOC/GIFINTO.DOC b/G/DOC/GIFINTO.DOC new file mode 100644 index 0000000..c33a271 --- /dev/null +++ b/G/DOC/GIFINTO.DOC @@ -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. diff --git a/G/DOC/GIFPOS.DOC b/G/DOC/GIFPOS.DOC new file mode 100644 index 0000000..f8fe0da --- /dev/null +++ b/G/DOC/GIFPOS.DOC @@ -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. diff --git a/G/DOC/GIFROTAT.DOC b/G/DOC/GIFROTAT.DOC new file mode 100644 index 0000000..ee9cbe7 --- /dev/null +++ b/G/DOC/GIFROTAT.DOC @@ -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. diff --git a/G/DOC/GIFRSIZE.DOC b/G/DOC/GIFRSIZE.DOC new file mode 100644 index 0000000..b426a0e --- /dev/null +++ b/G/DOC/GIFRSIZE.DOC @@ -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. diff --git a/G/DOC/GIFTEXT.DOC b/G/DOC/GIFTEXT.DOC new file mode 100644 index 0000000..f26ec07 --- /dev/null +++ b/G/DOC/GIFTEXT.DOC @@ -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. + diff --git a/G/DOC/GIFWEDGE.DOC b/G/DOC/GIFWEDGE.DOC new file mode 100644 index 0000000..4af4b92 --- /dev/null +++ b/G/DOC/GIFWEDGE.DOC @@ -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. + diff --git a/G/DOC/GIF_LIB.DOC b/G/DOC/GIF_LIB.DOC new file mode 100644 index 0000000..6e78254 --- /dev/null +++ b/G/DOC/GIF_LIB.DOC @@ -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); +} diff --git a/G/DOC/LIBERROR.DOC b/G/DOC/LIBERROR.DOC new file mode 100644 index 0000000..07a8477 --- /dev/null +++ b/G/DOC/LIBERROR.DOC @@ -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. diff --git a/G/DOC/RAW2GIF.DOC b/G/DOC/RAW2GIF.DOC new file mode 100644 index 0000000..b1d2d7b --- /dev/null +++ b/G/DOC/RAW2GIF.DOC @@ -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. diff --git a/G/DOC/RGB2GIF.DOC b/G/DOC/RGB2GIF.DOC new file mode 100644 index 0000000..5cb21c3 --- /dev/null +++ b/G/DOC/RGB2GIF.DOC @@ -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. diff --git a/G/DOC/RLE2GIF.DOC b/G/DOC/RLE2GIF.DOC new file mode 100644 index 0000000..eb46a0d --- /dev/null +++ b/G/DOC/RLE2GIF.DOC @@ -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). diff --git a/G/DOC/TEXT2GIF.DOC b/G/DOC/TEXT2GIF.DOC new file mode 100644 index 0000000..c93ebf7 --- /dev/null +++ b/G/DOC/TEXT2GIF.DOC @@ -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. diff --git a/G/DOS2UNIX b/G/DOS2UNIX new file mode 100644 index 0000000..d91eec0 --- /dev/null +++ b/G/DOS2UNIX @@ -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) diff --git a/G/GIF/BGI.EXE b/G/GIF/BGI.EXE new file mode 100644 index 0000000..01d37f8 Binary files /dev/null and b/G/GIF/BGI.EXE differ diff --git a/G/GIF/CHERYL.GIF b/G/GIF/CHERYL.GIF new file mode 100644 index 0000000..b250eec Binary files /dev/null and b/G/GIF/CHERYL.GIF differ diff --git a/G/GIF/DISCO.GIF b/G/GIF/DISCO.GIF new file mode 100644 index 0000000..f3d6b76 Binary files /dev/null and b/G/GIF/DISCO.GIF differ diff --git a/G/GIF/GIF.EXE b/G/GIF/GIF.EXE new file mode 100644 index 0000000..ebe73b2 Binary files /dev/null and b/G/GIF/GIF.EXE differ diff --git a/G/GIF/GIF2BGI.EXE b/G/GIF/GIF2BGI.EXE new file mode 100644 index 0000000..a585ccb Binary files /dev/null and b/G/GIF/GIF2BGI.EXE differ diff --git a/G/GIF/GIF2EPSN.EXE b/G/GIF/GIF2EPSN.EXE new file mode 100644 index 0000000..954b006 Binary files /dev/null and b/G/GIF/GIF2EPSN.EXE differ diff --git a/G/GIF/GIF2HERC.EXE b/G/GIF/GIF2HERC.EXE new file mode 100644 index 0000000..5057759 Binary files /dev/null and b/G/GIF/GIF2HERC.EXE differ diff --git a/G/GIF/GIF2PS.EXE b/G/GIF/GIF2PS.EXE new file mode 100644 index 0000000..51f9bf7 Binary files /dev/null and b/G/GIF/GIF2PS.EXE differ diff --git a/G/GIF/GIF2RGB.EXE b/G/GIF/GIF2RGB.EXE new file mode 100644 index 0000000..16f71ef Binary files /dev/null and b/G/GIF/GIF2RGB.EXE differ diff --git a/G/GIF/GIFCLRMP.EXE b/G/GIF/GIFCLRMP.EXE new file mode 100644 index 0000000..fa63834 Binary files /dev/null and b/G/GIF/GIFCLRMP.EXE differ diff --git a/G/GIF/GIFCOMB.EXE b/G/GIF/GIFCOMB.EXE new file mode 100644 index 0000000..aa5f4b0 Binary files /dev/null and b/G/GIF/GIFCOMB.EXE differ diff --git a/G/GIF/GIFFIX.EXE b/G/GIF/GIFFIX.EXE new file mode 100644 index 0000000..4adf007 Binary files /dev/null and b/G/GIF/GIFFIX.EXE differ diff --git a/G/GIF/GIFFLIP.EXE b/G/GIF/GIFFLIP.EXE new file mode 100644 index 0000000..93012b0 Binary files /dev/null and b/G/GIF/GIFFLIP.EXE differ diff --git a/G/GIF/GIFHISTO.EXE b/G/GIF/GIFHISTO.EXE new file mode 100644 index 0000000..bd621a4 Binary files /dev/null and b/G/GIF/GIFHISTO.EXE differ diff --git a/G/GIF/GIFINTER.EXE b/G/GIF/GIFINTER.EXE new file mode 100644 index 0000000..54699c4 Binary files /dev/null and b/G/GIF/GIFINTER.EXE differ diff --git a/G/GIF/GIFINTO.EXE b/G/GIF/GIFINTO.EXE new file mode 100644 index 0000000..b6ca472 Binary files /dev/null and b/G/GIF/GIFINTO.EXE differ diff --git a/G/GIF/GIFPOS.EXE b/G/GIF/GIFPOS.EXE new file mode 100644 index 0000000..75fe0f6 Binary files /dev/null and b/G/GIF/GIFPOS.EXE differ diff --git a/G/GIF/GIFROTAT.EXE b/G/GIF/GIFROTAT.EXE new file mode 100644 index 0000000..441242a Binary files /dev/null and b/G/GIF/GIFROTAT.EXE differ diff --git a/G/GIF/GIFRSIZE.EXE b/G/GIF/GIFRSIZE.EXE new file mode 100644 index 0000000..da1c387 Binary files /dev/null and b/G/GIF/GIFRSIZE.EXE differ diff --git a/G/GIF/GIFTEXT.EXE b/G/GIF/GIFTEXT.EXE new file mode 100644 index 0000000..09b1d57 Binary files /dev/null and b/G/GIF/GIFTEXT.EXE differ diff --git a/G/GIF/GIFWEDGE.EXE b/G/GIF/GIFWEDGE.EXE new file mode 100644 index 0000000..7fa9cc8 Binary files /dev/null and b/G/GIF/GIFWEDGE.EXE differ diff --git a/G/GIF/HERC2GIF.EXE b/G/GIF/HERC2GIF.EXE new file mode 100644 index 0000000..3873a90 Binary files /dev/null and b/G/GIF/HERC2GIF.EXE differ diff --git a/G/GIF/PORSCHE.GIF b/G/GIF/PORSCHE.GIF new file mode 100644 index 0000000..916014e Binary files /dev/null and b/G/GIF/PORSCHE.GIF differ diff --git a/G/GIF/RAW2GIF.EXE b/G/GIF/RAW2GIF.EXE new file mode 100644 index 0000000..83a9333 Binary files /dev/null and b/G/GIF/RAW2GIF.EXE differ diff --git a/G/GIF/RGB2GIF.EXE b/G/GIF/RGB2GIF.EXE new file mode 100644 index 0000000..b9e08de Binary files /dev/null and b/G/GIF/RGB2GIF.EXE differ diff --git a/G/GIF/SOLID2.GIF b/G/GIF/SOLID2.GIF new file mode 100644 index 0000000..4e9524b Binary files /dev/null and b/G/GIF/SOLID2.GIF differ diff --git a/G/GIF/TEXT2GIF.EXE b/G/GIF/TEXT2GIF.EXE new file mode 100644 index 0000000..27dd5a7 Binary files /dev/null and b/G/GIF/TEXT2GIF.EXE differ diff --git a/G/LIB/DEV2GIF.C b/G/LIB/DEV2GIF.C new file mode 100644 index 0000000..e79c0b6 --- /dev/null +++ b/G/LIB/DEV2GIF.C @@ -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 +#include +#include +#endif /* __MSDOS__ */ + +#ifdef __SGI_GL__ +#include +#endif /* __SGI_GL__ */ + +#ifdef __X11__ +#include +#endif /* __X11__ */ + +#include +#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; +} + + + + + + + + + diff --git a/G/LIB/DGIF_LIB.C b/G/LIB/DGIF_LIB.C new file mode 100644 index 0000000..6719cee --- /dev/null +++ b/G/LIB/DGIF_LIB.C @@ -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 +#include +#include +#include +#else +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#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; +} diff --git a/G/LIB/EGIF_LIB.C b/G/LIB/EGIF_LIB.C new file mode 100644 index 0000000..d3103ea --- /dev/null +++ b/G/LIB/EGIF_LIB.C @@ -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 +#include +#include +#else +#include +#include +#ifdef R6000 +#include +#endif +#endif /* __MSDOS__ */ + +#include +#include +#include +#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; +} diff --git a/G/LIB/GETARG.C b/G/LIB/GETARG.C new file mode 100644 index 0000000..819bf3f --- /dev/null +++ b/G/LIB/GETARG.C @@ -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 +#include +#endif /* __MSDOS__ */ + +#ifdef USE_VARARGS +#include +#endif /* USE_VARARGS */ + +#include +#include +#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 */ diff --git a/G/LIB/GETARG.H b/G/LIB/GETARG.H new file mode 100644 index 0000000..e09c59c --- /dev/null +++ b/G/LIB/GETARG.H @@ -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 */ diff --git a/G/LIB/GIF_ERR.C b/G/LIB/GIF_ERR.C new file mode 100644 index 0000000..8cb91f9 --- /dev/null +++ b/G/LIB/GIF_ERR.C @@ -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 +#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); +} diff --git a/G/LIB/GIF_HASH.C b/G/LIB/GIF_HASH.C new file mode 100644 index 0000000..d30b40e --- /dev/null +++ b/G/LIB/GIF_HASH.C @@ -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 +#include +#include +#else +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#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 */ diff --git a/G/LIB/GIF_HASH.H b/G/LIB/GIF_HASH.H new file mode 100644 index 0000000..08ac702 --- /dev/null +++ b/G/LIB/GIF_HASH.H @@ -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 \ No newline at end of file diff --git a/G/LIB/GIF_LIB.H b/G/LIB/GIF_LIB.H new file mode 100644 index 0000000..d4b9834 --- /dev/null +++ b/G/LIB/GIF_LIB.H @@ -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 */ diff --git a/G/LIB/GIF_LIBC.LIB b/G/LIB/GIF_LIBC.LIB new file mode 100644 index 0000000..3f66058 Binary files /dev/null and b/G/LIB/GIF_LIBC.LIB differ diff --git a/G/LIB/GIF_LIBC.LST b/G/LIB/GIF_LIBC.LST new file mode 100644 index 0000000..4b4907b --- /dev/null +++ b/G/LIB/GIF_LIBC.LST @@ -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 diff --git a/G/LIB/GIF_LIBH.LIB b/G/LIB/GIF_LIBH.LIB new file mode 100644 index 0000000..39dd408 Binary files /dev/null and b/G/LIB/GIF_LIBH.LIB differ diff --git a/G/LIB/GIF_LIBH.LST b/G/LIB/GIF_LIBH.LST new file mode 100644 index 0000000..4410e2b --- /dev/null +++ b/G/LIB/GIF_LIBH.LST @@ -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 diff --git a/G/LIB/GIF_LIBL.LIB b/G/LIB/GIF_LIBL.LIB new file mode 100644 index 0000000..9839f37 Binary files /dev/null and b/G/LIB/GIF_LIBL.LIB differ diff --git a/G/LIB/GIF_LIBL.LST b/G/LIB/GIF_LIBL.LST new file mode 100644 index 0000000..03e762a --- /dev/null +++ b/G/LIB/GIF_LIBL.LST @@ -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 diff --git a/G/LIB/GIF_LIBM.LIB b/G/LIB/GIF_LIBM.LIB new file mode 100644 index 0000000..20dd32a Binary files /dev/null and b/G/LIB/GIF_LIBM.LIB differ diff --git a/G/LIB/GIF_LIBM.LST b/G/LIB/GIF_LIBM.LST new file mode 100644 index 0000000..ebb2a3f --- /dev/null +++ b/G/LIB/GIF_LIBM.LST @@ -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 diff --git a/G/LIB/GIF_LIBS.LIB b/G/LIB/GIF_LIBS.LIB new file mode 100644 index 0000000..1612f3d Binary files /dev/null and b/G/LIB/GIF_LIBS.LIB differ diff --git a/G/LIB/GIF_LIBS.LST b/G/LIB/GIF_LIBS.LST new file mode 100644 index 0000000..39a6852 --- /dev/null +++ b/G/LIB/GIF_LIBS.LST @@ -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 diff --git a/G/LIB/MAKEFILE.TC b/G/LIB/MAKEFILE.TC new file mode 100644 index 0000000..a6193a7 --- /dev/null +++ b/G/LIB/MAKEFILE.TC @@ -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 + diff --git a/G/LIB/MAKEFILE.UNX b/G/LIB/MAKEFILE.UNX new file mode 100644 index 0000000..c54779f --- /dev/null +++ b/G/LIB/MAKEFILE.UNX @@ -0,0 +1,72 @@ +# +# This is the make file for the lib subdirectory of the GIF library +# In order to run it gcc is assumed to be available. +# +# Gershon Elber, Jun 1989 +# + +# +# Where all the include files are: +INCS = -I. + +# +# What devices we should be able to grab into gif images. Note that if +# you enable them the associated library must be available at link time. +# Avaiable devices: +# 1. EGA, VGA, SVGA (800x600), Hercules - all on IBM PC only. +# 2. SGI 4D Irix using gl library (Add -D__SGI_GL__). +# 3. X11 using libX.a (Add -D__X11__) +DEVS = -D__SGI_GL__ + +# +# These are the flags for gcc, in BSD4.3 or Sun O.S. 4.0.3 +# +# If your system has all function prototypes for gcc, replace all +# the -Wxxx with -Wall. I can not add -Wimplicit as my system uses old cc +# h files. +# +# CC = gcc +# +# CFLAGS = -O -c -W -Wreturn-type -Wcomment +# CFLAGS = -g -pg -c -W -Wreturn-type -Wcomment +# +# for sun 4 (gunnars@ifi.uib.no). Tested using gcc 1.39. +# +# CFLAGS = -O -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS +# CFLAGS = -g -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS + +# +# These are the flags for cc on SGI iris4d. O.S. IRIX 3.2 +# +CC = cc +# +CFLAGS = -O -c -DSYSV -DNO_VOID_PTR -DUSE_VARARGS -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4 +# CFLAGS = -g -p -c -DSYSV -DNO_VOID_PTR -DUSE_VARARGS -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4 + +# +# These are the flags for xlc, ansi compiler for IBM R6000 +# +# CC = xlc +# +# CFLAGS = -O -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000 +# CFLAGS = -g -pg -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000 + +OBJS = dev2gif.o egif_lib.o dgif_lib.o gif_hash.o gif_err.o \ + quantize.o qprintf.o getarg.o + +.c.o: + $(CC) $(INCS) $(DEVS) $(CFLAGS) $< + +libgif.a: $(OBJS) + rm -f libgif.a + ar rcv libgif.a *.o + -ranlib libgif.a + +dev2gif.o: gif_lib.h +egif_lib.o: gif_lib.h gif_hash.h +dgif_lib.o: gif_lib.h gif_hash.h +gif_hash.o: gif_lib.h gif_hash.h +gif_err.o: gif_lib.h +quantize.o: gif_lib.h +qprintf.o: gif_lib.h +getarg.o: getarg.h diff --git a/G/LIB/QPRINTF.C b/G/LIB/QPRINTF.C new file mode 100644 index 0000000..6ab343e --- /dev/null +++ b/G/LIB/QPRINTF.C @@ -0,0 +1,55 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * +****************************************************************************** +* Module to emulate a printf with a possible quite (disable mode.) * +* A global variable GifQuitePrint controls the printing of this routine * +****************************************************************************** +* History: * +* 12 May 91 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#include + +#ifdef USE_VARARGS +#include +#else +#include +#endif /* USE_VARARGS */ + +#include "gif_lib.h" + +#ifdef __MSDOS__ +int GifQuitePrint = FALSE; +#else +int GifQuitePrint = TRUE; +#endif /* __MSDOS__ */ + +/***************************************************************************** +* Same as fprintf to stderr but with optional print. * +*****************************************************************************/ +#ifdef USE_VARARGS +void GifQprintf(int va_alist) +{ + char *Format, Line[128]; + va_list ArgPtr; + + va_start(ArgPtr); + Format = va_arg(ArgPtr, char *); +#else +void GifQprintf(char *Format, ...) +{ + char Line[128]; + va_list ArgPtr; + + va_start(ArgPtr, Format); +#endif /* USE_VARARGS */ + + if (GifQuitePrint) return; + + vsprintf(Line, Format, ArgPtr); + va_end(ArgPtr); + + fputs(Line, stderr); +} diff --git a/G/LIB/QUANTIZE.C b/G/LIB/QUANTIZE.C new file mode 100644 index 0000000..f0f1729 --- /dev/null +++ b/G/LIB/QUANTIZE.C @@ -0,0 +1,335 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber IBM PC Ver 0.1, Jun. 1989 * +****************************************************************************** +* Module to quatize high resolution image into lower one. You may want to * +* peek into the following article this code is based on: * +* "Color Image Quantization for frame buffer Display", by Paul Heckbert * +* SIGGRAPH 1982 page 297-307. * +****************************************************************************** +* History: * +* 5 Jan 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include "gif_lib.h" + +#define PROGRAM_NAME "GIF_LIBRARY" + +#define ABS(x) ((x) > 0 ? (x) : (-(x))) + +/* The colors are stripped to 5 bits per primary color if non MSDOS system */ +/* or to 4 (not enough memory...) if MSDOS as first step. */ +#ifdef __MSDOS__ +#define COLOR_ARRAY_SIZE 4096 +#define BITS_PER_PRIM_COLOR 4 +#define MAX_PRIM_COLOR 0x0f +#else +#define COLOR_ARRAY_SIZE 32768 +#define BITS_PER_PRIM_COLOR 5 +#define MAX_PRIM_COLOR 0x1f +#endif /* __MSDOS__ */ + +extern int _GifError; + +#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 SortRGBAxis; + +typedef struct QuantizedColorType { + GifByteType RGB[3]; + GifByteType NewColorIndex; + long Count; + struct QuantizedColorType *Pnext; +} QuantizedColorType; + +typedef struct NewColorMapType { + GifByteType RGBMin[3], RGBWidth[3]; + unsigned int NumEntries;/* # of QuantizedColorType in linked list below. */ + long Count; /* Total number of pixels in all the entries. */ + QuantizedColorType *QuantizedColors; +} NewColorMapType; + +static int SubdivColorMap(NewColorMapType *NewColorSubdiv, + unsigned int ColorMapSize, + unsigned int *NewColorMapSize); +#ifdef __MSDOS__ +static int SortCmpRtn(const VoidPtr Entry1, const VoidPtr Entry2); +#else +static int SortCmpRtn(VoidPtr Entry1, VoidPtr Entry2); +#endif /* __MSDOS__ */ + +/****************************************************************************** +* Quantize high resolution image into lower one. Input image consists of a * +* 2D array for each of the RGB colors with size Width by Height. There is no * +* Color map for the input. Output is a quantized image with 2D array of * +* indexes into the output color map. * +* Note input image can be 24 bits at the most (8 for red/green/blue) and * +* the output has 256 colors at the most (256 entries in the color map.). * +* ColorMapSize specifies size of color map up to 256 and will be updated to * +* real size before returning. * +* Also non of the parameter are allocated by this routine. * +* This function returns GIF_OK if succesfull, GIF_ERROR otherwise. * +******************************************************************************/ +int QuantizeBuffer(unsigned int Width, unsigned int Height, int *ColorMapSize, + GifByteType *RedInput, GifByteType *GreenInput, GifByteType *BlueInput, + GifByteType *OutputBuffer, GifColorType *OutputColorMap) +{ + unsigned int i, j, Index, NewColorMapSize, NumOfEntries, MaxRGBError[3]; + long Red, Green, Blue; + NewColorMapType NewColorSubdiv[256]; + QuantizedColorType *ColorArrayEntries, *QuantizedColor; + + if ((ColorArrayEntries = (QuantizedColorType *) + malloc(sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE)) == NULL) { + _GifError = E_GIF_ERR_NOT_ENOUGH_MEM; + return GIF_ERROR; + } + + for (i = 0; i < COLOR_ARRAY_SIZE; i++) { + ColorArrayEntries[i].RGB[0]= i >> (2 * BITS_PER_PRIM_COLOR); + ColorArrayEntries[i].RGB[1] = (i >> BITS_PER_PRIM_COLOR) & + MAX_PRIM_COLOR; + ColorArrayEntries[i].RGB[2] = i & MAX_PRIM_COLOR; + ColorArrayEntries[i].Count = 0; + } + + /* Sample the colors and their distribution: */ + for (i = 0; i < Width * Height; i++) { + Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) + << (2 * BITS_PER_PRIM_COLOR)) + + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) + << BITS_PER_PRIM_COLOR) + + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR)); + ColorArrayEntries[Index].Count++; + } + + /* Put all the colors in the first entry of the color map, and call the */ + /* recursive subdivision process. */ + for (i = 0; i < 256; i++) { + NewColorSubdiv[i].QuantizedColors = NULL; + NewColorSubdiv[i].Count = NewColorSubdiv[i].NumEntries = 0; + for (j = 0; j < 3; j++) { + NewColorSubdiv[i].RGBMin[j] = 0; + NewColorSubdiv[i].RGBWidth[j] = 255; + } + } + + /* Find the non empty entries in the color table and chain them: */ + for (i = 0; i < COLOR_ARRAY_SIZE; i++) + if (ColorArrayEntries[i].Count > 0) break; + QuantizedColor = NewColorSubdiv[0].QuantizedColors = &ColorArrayEntries[i]; + NumOfEntries = 1; + while (++i < COLOR_ARRAY_SIZE) + if (ColorArrayEntries[i].Count > 0) { + QuantizedColor -> Pnext = &ColorArrayEntries[i]; + QuantizedColor = &ColorArrayEntries[i]; + NumOfEntries++; + } + QuantizedColor -> Pnext = NULL; + + NewColorSubdiv[0].NumEntries = NumOfEntries;/* Different sampled colors. */ + NewColorSubdiv[0].Count = ((long) Width) * Height; /* Pixels. */ + NewColorMapSize = 1; + if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) != + GIF_OK) { + free((char *) ColorArrayEntries); + return GIF_ERROR; + } + if (NewColorMapSize < *ColorMapSize) { + /* And clear rest of color map: */ + for (i = NewColorMapSize; i < *ColorMapSize; i++) + OutputColorMap[i].Red = + OutputColorMap[i].Green = + OutputColorMap[i].Blue = 0; + } + + /* Average the colors in each entry to be the color to be used in the */ + /* output color map, and plug it into the output color map itself. */ + for (i = 0; i < NewColorMapSize; i++) { + if ((j = NewColorSubdiv[i].NumEntries) > 0) { + QuantizedColor = NewColorSubdiv[i].QuantizedColors; + Red = Green = Blue = 0; + while (QuantizedColor) { + QuantizedColor -> NewColorIndex = i; + Red += QuantizedColor -> RGB[0]; + Green += QuantizedColor -> RGB[1]; + Blue += QuantizedColor -> RGB[2]; + QuantizedColor = QuantizedColor -> Pnext; + } + OutputColorMap[i].Red = (Red << (8 - BITS_PER_PRIM_COLOR)) / j; + OutputColorMap[i].Green = (Green << (8 - BITS_PER_PRIM_COLOR)) / j; + OutputColorMap[i].Blue= (Blue << (8 - BITS_PER_PRIM_COLOR)) / j; + } + else + GIF_MESSAGE("Null entry in quantized color map - thats weird."); + } + + /* Finally scan the input buffer again and put the mapped index in the */ + /* output buffer. */ + MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0; + for (i = 0; i < Width * Height; i++) { + Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) + << (2 * BITS_PER_PRIM_COLOR)) + + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) + << BITS_PER_PRIM_COLOR) + + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR)); + Index = ColorArrayEntries[Index].NewColorIndex; + OutputBuffer[i] = Index; + if (MaxRGBError[0] < ABS(OutputColorMap[Index].Red - RedInput[i])) + MaxRGBError[0] = ABS(OutputColorMap[Index].Red - RedInput[i]); + if (MaxRGBError[1] < ABS(OutputColorMap[Index].Green - GreenInput[i])) + MaxRGBError[1] = ABS(OutputColorMap[Index].Green - GreenInput[i]); + if (MaxRGBError[2] < ABS(OutputColorMap[Index].Blue - BlueInput[i])) + MaxRGBError[2] = ABS(OutputColorMap[Index].Blue - BlueInput[i]); + } + +#ifdef DEBUG + fprintf(stderr, + "Quantization L(0) errors: Red = %d, Green = %d, Blue = %d.\n", + MaxRGBError[0], MaxRGBError[1], MaxRGBError[2]); +#endif /* DEBUG */ + + free((char *) ColorArrayEntries); + + *ColorMapSize = NewColorMapSize; + + return GIF_OK; +} + +/****************************************************************************** +* Routine to subdivide the RGB space recursively using median cut in each * +* axes alternatingly until ColorMapSize different cubes exists. * +* The biggest cube in one dimension is subdivide unless it has only one entry.* +* Returns GIF_ERROR if failed, otherwise GIF_OK. * +******************************************************************************/ +static int SubdivColorMap(NewColorMapType *NewColorSubdiv, + unsigned int ColorMapSize, + unsigned int *NewColorMapSize) +{ + int MaxSize; + unsigned int i, j, Index = 0, NumEntries, MinColor, MaxColor; + long Sum, Count; + QuantizedColorType *QuantizedColor, **SortArray; + + while (ColorMapSize > *NewColorMapSize) { + /* Find candidate for subdivision: */ + MaxSize = -1; + for (i = 0; i < *NewColorMapSize; i++) { + for (j = 0; j < 3; j++) { + if (((int) NewColorSubdiv[i].RGBWidth[j]) > MaxSize && + NewColorSubdiv[i].NumEntries > 1) { + MaxSize = NewColorSubdiv[i].RGBWidth[j]; + Index = i; + SortRGBAxis = j; + } + } + } + + if (MaxSize == -1) + return GIF_OK; + + /* Split the entry Index into two along the axis SortRGBAxis: */ + + /* Sort all elements in that entry along the given axis and split at */ + /* the median. */ + if ((SortArray = (QuantizedColorType **) + malloc(sizeof(QuantizedColorType *) * + NewColorSubdiv[Index].NumEntries)) == NULL) + return GIF_ERROR; + for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors; + j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL; + j++, QuantizedColor = QuantizedColor -> Pnext) + SortArray[j] = QuantizedColor; + qsort(SortArray, NewColorSubdiv[Index].NumEntries, + sizeof(QuantizedColorType *), SortCmpRtn); + + /* Relink the sorted list into one: */ + for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++) + SortArray[j] -> Pnext = SortArray[j + 1]; + SortArray[NewColorSubdiv[Index].NumEntries - 1] -> Pnext = NULL; + NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0]; + free((char *) SortArray); + + /* Now simply add the Counts until we have half of the Count: */ + Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor -> Count; + NumEntries = 1; + Count = QuantizedColor -> Count; + while ((Sum -= QuantizedColor -> Pnext -> Count) >= 0 && + QuantizedColor -> Pnext != NULL && + QuantizedColor -> Pnext -> Pnext != NULL) { + QuantizedColor = QuantizedColor -> Pnext; + NumEntries++; + Count += QuantizedColor -> Count; + } + /* Save the values of the last color of the first half, and first */ + /* of the second half so we can update the Bounding Boxes later. */ + /* Also as the colors are quantized and the BBoxes are full 0..255, */ + /* they need to be rescaled. */ + MaxColor = QuantizedColor -> RGB[SortRGBAxis];/* Max. of first half. */ + MinColor = QuantizedColor -> Pnext -> RGB[SortRGBAxis];/* of second. */ + MaxColor <<= (8 - BITS_PER_PRIM_COLOR); + MinColor <<= (8 - BITS_PER_PRIM_COLOR); + + /* Partition right here: */ + NewColorSubdiv[*NewColorMapSize].QuantizedColors = + QuantizedColor -> Pnext; + QuantizedColor -> Pnext = NULL; + NewColorSubdiv[*NewColorMapSize].Count = Count; + NewColorSubdiv[Index].Count -= Count; + NewColorSubdiv[*NewColorMapSize].NumEntries = + NewColorSubdiv[Index].NumEntries - NumEntries; + NewColorSubdiv[Index].NumEntries = NumEntries; + for (j = 0; j < 3; j++) { + NewColorSubdiv[*NewColorMapSize].RGBMin[j] = + NewColorSubdiv[Index].RGBMin[j]; + NewColorSubdiv[*NewColorMapSize].RGBWidth[j] = + NewColorSubdiv[Index].RGBWidth[j]; + } + NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] = + NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] + + NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - + MinColor; + NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor; + + NewColorSubdiv[Index].RGBWidth[SortRGBAxis] = + MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis]; + + (*NewColorMapSize)++; + } + + return GIF_OK; +} + +/****************************************************************************** +* Routine called by qsort to compare to entries. * +******************************************************************************/ +#ifdef __MSDOS__ +static int SortCmpRtn(const VoidPtr Entry1, const VoidPtr Entry2) +#else +static int SortCmpRtn(VoidPtr Entry1, VoidPtr Entry2) +#endif /* __MSDOS__ */ +{ + return (* ((QuantizedColorType **) Entry1)) -> RGB[SortRGBAxis] - + (* ((QuantizedColorType **) Entry2)) -> RGB[SortRGBAxis]; +} diff --git a/G/MAKE-IBM.BAT b/G/MAKE-IBM.BAT new file mode 100644 index 0000000..05b3f4f --- /dev/null +++ b/G/MAKE-IBM.BAT @@ -0,0 +1,8 @@ +cd lib +make -fmakefile.tc +cd .. + +cd util +make -fmakefile.tc +cd .. + \ No newline at end of file diff --git a/G/MAKE-UNX b/G/MAKE-UNX new file mode 100644 index 0000000..7ab4ad6 --- /dev/null +++ b/G/MAKE-UNX @@ -0,0 +1,13 @@ +#/bin/csh -f +# +# Gershon Elber, Feb 90. +# + +cd lib +make -f makefile.unx libgif.a +cd .. +cd util +make -f makefile.unx all +make -f makefile.unx rle # Only if you have the rle tool kit! +cd .. +strip bin/* diff --git a/G/MANIFEST b/G/MANIFEST new file mode 100644 index 0000000..03b7f67 --- /dev/null +++ b/G/MANIFEST @@ -0,0 +1,108 @@ +D:\C\GIF: +total 15 +-rwx--a 86 May 13 18:07 BACKUP.BAT +drw---- Dec 08 1990 BIN +-rw---- 5065 Nov 13 1990 COMPILE.ME +drw---- Dec 08 1990 DOC +-rw---- 671 May 05 10:10 DOS2UNIX +drw---- Dec 08 1990 LIB +-rwx--- 74 Feb 24 1990 MAKE-IBM.BAT +-rw---- 200 Feb 27 1990 MAKE-UNX +drw---- Dec 08 1990 PIC +-rw---- 3397 Nov 13 1990 README.1ST +-rw---- 1747 Mar 27 21:33 SOURCES.GET +-rwx--- 2772 Nov 12 1990 TEST-IBM.BAT +-rw---- 2191 May 05 13:39 TEST-UNX +-rw---a 988 May 13 18:09 UPDATE.NEW +drw---- Dec 08 1990 UTIL + +D:\C\GIF\BIN: +total 1 +-rw---- 184 Feb 26 1990 DUMMY + +D:\C\GIF\DOC: +total 41 +-rw---- 1280 Feb 23 1990 GENERAL.DOC +-rw---a 3493 May 13 17:36 GIF2BGI.DOC +-rw---a 2572 May 13 17:23 GIF2EPSN.DOC +-rw---a 3640 May 13 17:25 GIF2HERC.DOC +-rw---a 678 May 13 17:41 GIF2IRIS.DOC +-rw---a 1391 May 13 17:26 GIF2PS.DOC +-rw---a 771 May 13 17:26 GIF2RLE.DOC +-rw---a 1087 May 13 17:27 GIF2X11.DOC +-rw---a 1222 May 13 17:28 GIFASM.DOC +-rw---a 1897 May 13 17:28 GIFBG.DOC +-rw---a 1490 May 13 17:29 GIFCLIP.DOC +-rw---a 1142 May 13 17:30 GIFCLRMP.DOC +-rw---a 1206 May 13 17:30 GIFCOMB.DOC +-rw---a 582 May 13 17:31 GIFFIX.DOC +-rw---a 923 May 13 17:32 GIFFLIP.DOC +-rw---a 1625 May 13 17:33 GIFHISTO.DOC +-rw---a 631 May 13 17:33 GIFINTER.DOC +-rw---a 1043 May 13 17:33 GIFINTO.DOC +-rw---a 1114 May 13 17:34 GIFPOS.DOC +-rw---a 893 May 13 17:34 GIFRSIZE.DOC +-rw---a 1446 May 13 17:35 GIFTEXT.DOC +-rw---a 862 May 13 17:35 GIFWEDGE.DOC +-rw---- 18592 Aug 15 1990 GIF_LIB.DOC +-rw---- 5320 Feb 23 1990 LIBERROR.DOC +-rw---a 1246 May 13 17:36 RAW2GIF.DOC +-rw---a 1028 May 13 17:36 RLE2GIF.DOC +-rw---a 1963 May 13 17:37 TEXT2GIF.DOC + +D:\C\GIF\LIB: +total 100 +-rw---a 16668 Oct 17 1990 DEV2GIF.C +-rw---a 30190 May 05 13:11 DGIF_LIB.C +-rw---a 27253 Oct 17 1990 EGIF_LIB.C +-rw---a 25555 Sep 06 1990 GETARG.C +-rw---a 1040 Oct 17 1990 GETARG.H +-rw---a 3968 Sep 06 1990 GIF_ERR.C +-rw---a 5581 Sep 06 1990 GIF_HASH.C +-rw---a 1487 Feb 23 1990 GIF_HASH.H +-rw---a 7620 May 12 20:04 GIF_LIB.H +-rw---a 25088 May 12 20:22 GIF_LIBL.LIB +-rw---a 1218 May 12 20:22 GIF_LIBL.LST +-rw---a 1514 May 12 20:04 MAKEFILE.TC +-rw---a 2015 May 12 20:02 MAKEFILE.UNX +-rw---a 1609 May 12 20:22 QPRINTF.C +-rw---a 12813 Sep 06 1990 QUANTIZE.C + +D:\C\GIF\PIC: +total 24 +-rw---- 21504 May 04 1988 CHERYL.GIF +-rw---- 6144 May 05 1988 PORSCHE.GIF +-rw---- 18599 Sep 03 1990 SOLID2.GIF + +D:\C\GIF\UTIL: +total 239 +-rw---a 28863 May 12 20:26 GIF2BGI.C +-rw---a 20860 May 12 22:13 GIF2EPSN.C +-rw---a 35693 May 12 21:41 GIF2HERC.C +-rw---a 9075 May 12 22:13 GIF2IRIS.C +-rw---a 12351 May 12 22:13 GIF2PS.C +-rw---a 8996 May 12 21:40 GIF2RLE.C +-rw---a 17657 May 12 21:44 GIF2X11.C +-rw---a 11474 May 12 21:44 GIFASM.C +-rw---a 11723 May 12 21:46 GIFBG.C +-rw---a 9194 May 12 21:48 GIFCLIP.C +-rw---a 9979 May 12 21:49 GIFCLRMP.C +-rw---a 12624 May 12 21:50 GIFCOMB.C +-rw---- 2401 May 04 14:53 GIFDEBUG.DSK +-rw---- 11415 May 04 14:53 GIFDEBUG.PRJ +-rw---a 7336 May 12 21:52 GIFFIX.C +-rw---a 12280 May 12 21:53 GIFFLIP.C +-rw---a 9414 May 12 21:54 GIFHISTO.C +-rw---a 9856 May 12 21:56 GIFINTER.C +-rw---a 5236 May 12 21:58 GIFINTO.C +-rw---a 7385 May 12 21:58 GIFPOS.C +-rw---a 12345 May 12 21:59 GIFRSIZE.C +-rw---a 14477 May 12 22:30 GIFTEXT.C +-rw---a 5862 May 12 22:02 GIFWEDGE.C +-rw---- 1068 Sep 03 1990 HERC2GIF.C +-rw---- 2050 Dec 01 1990 MAKDEBUG.TC +-rw---- 3996 May 04 14:14 MAKEFILE.TC +-rw---- 4825 May 05 13:41 MAKEFILE.UNX +-rw---a 8528 May 12 22:03 RAW2GIF.C +-rw---a 7533 May 12 22:04 RLE2GIF.C +-rw---a 16524 May 12 22:06 TEXT2GIF.C diff --git a/G/PIC/CHERYL.GIF b/G/PIC/CHERYL.GIF new file mode 100644 index 0000000..b250eec Binary files /dev/null and b/G/PIC/CHERYL.GIF differ diff --git a/G/PIC/PORSCHE.GIF b/G/PIC/PORSCHE.GIF new file mode 100644 index 0000000..916014e Binary files /dev/null and b/G/PIC/PORSCHE.GIF differ diff --git a/G/PIC/SOLID2.GIF b/G/PIC/SOLID2.GIF new file mode 100644 index 0000000..4e9524b Binary files /dev/null and b/G/PIC/SOLID2.GIF differ diff --git a/G/README.1ST b/G/README.1ST new file mode 100644 index 0000000..638da21 --- /dev/null +++ b/G/README.1ST @@ -0,0 +1,52 @@ + The Graphics Interchange Format(c) is the Copyright property of +CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe +Incorporated. + + This is a package I wrote so that images can be generated as easy as +possible using GIF format. I needed such routines, and since I did not find +anything like this (at list not free) I decided to write one... + This package is FREE for non commercial usage. You can do whatever +you like with it provided you do not charge anything for it or for a program +that uses it. More then that, if you release the source for your program, the +source of this package you used should also be included (with my name on +it...). You may NOT charge money for the sources as well, in that case. + I am releasing the sources since lots of peoples expressed interest +in such a beast, on usenet, in the last few month. + I will NOT be hold responsible for any damage of any kind it may +cause you. Use it at your own risk. + In order to compile it, please read the file COMPILE.ME. I uses TC++ +2.0 so other compiler owners are on their own. The package has been ported to +unix machine on various platforms (see compile.me). + You will find .\doc with documents on all the utilities and the library +itself. + Only one of the images on .\pic was actually generated by me - +solid2.gif, which is binary image rendered using a solid modeller I have +developed named IRIT. The other two were released to usenet few month ago. +I do not think so, but let me know if I violate anything here. + Few final remarks. While 'playing' with the GIF format, I found few +holes in it, or in some of its implementations: +1. There is no explicit way one can specify comments in images, which can be + extremely useful. I used one of the extensions block to implements that. + The problem is that some of the gif viewer I tested (no names) died on + extension block (!?), so I decided not to use them in any of the utilities + although the library do support it, and if you are going to use only it + you can safely use the comments calls. Any better solution? +2. Some viewer even ignore the fact that one GIF file can hold few images. + I consider this property extremely useful (some of the utilities actually + manipulate exactly that - gifasm for example), and fully support it. I + think that a failure of a view program (or any GIF manipulator) here, + should be considered a bug. +3. One problem in the GIF format, I dont have simple solution to: it is the + limit of only 8bits per color. The importance of bigger width, is not only + for higher image quality. One can save other pixel properties in addition, + such as coverage (alpha channel as it is called in the rle utah raster + toolkit). The only solution I can thing of, is to generate few GIF files + in parallel - one for the pixel color, and the other for coverage. The + coverage property is extremely useful for utilities such as gifbg - back + ground color generator, and which can be composed with the image using + gifcomb. + +have fun + +Gershon +gershon@cs.utah.edu diff --git a/G/SOURCES.GET b/G/SOURCES.GET new file mode 100644 index 0000000..f3e6b3d --- /dev/null +++ b/G/SOURCES.GET @@ -0,0 +1,29 @@ +This file describes the condition in which you can use these sources: + +1. These sources are my property and should hold my name on them in + any circumstances. +2. You are given these sources FREE. Therefore I will not be responsible + for ANY damage, direct or indirect resulted from the use or misusage + of these sources. Use them at your own responsibility/risk. +3. You are given these sources FREE. You can use any portion of these + sources in any program you wish, following 1 and 2 above, provided that + that program is also distributed FREE. You do not have to distribute + your sources, but if you do you may include my sources as well, again + following 1 and 2 above. No part of this code should be sold nor be + part of a commercial program or a program sold for money. +4. Since you were given these sources FREE, you will not charge any money + for redistributing them. You may charge reasonable amount of money + (<$10) for your redistribution only. +5. There will be no restriction on the redistribution of this package unless + imposed specifically by me. You may redistribute, following 4, this package + only in its current form and content. You may only change the type of + archiver to pack this set of files. If part of this code is used in another + FREE program and distributed in source code form, you must provide a pointer + to the original package (this one) in your documentation. This is the only + form part of this package may be redistributed (see also 6). +6. If you modify any of these sources and wish to redistribute them under + similar term, you may do so but must include a document describing the + type of change and by whom made. + +Gershon +gershon@cs.utah.edu diff --git a/G/TEST-IBM.BAT b/G/TEST-IBM.BAT new file mode 100644 index 0000000..d167229 --- /dev/null +++ b/G/TEST-IBM.BAT @@ -0,0 +1,96 @@ +@echo off +rem +rem Tests for the gif_lib utilities. +rem Usage: +rem testgif [gif_dir] [display_prgm] +rem +rem This test assumes the gif_lib utilities are available from one of the +rem path directorys, and that DIR is set (directly or through command line) +rem to the directory holf these gif files: +rem 1. SOLID2.GIF +rem 2. CHERYL.GIF +rem 3. PORSCHE.GIF +rem In addition, set DISPLAY ( directly or through command line) to the +rem program to display gif files in our system. +rem As this batch file intensively uses pipes which on msdos are saved as +rem files on CURRENT disk, it is going to be a good idea to execute this batch +rem from a ram disk. + +set GIF_DIR=d:\c\gif\pic\ +if not x%1 == x set GIF_DIR = %1 + +rem +rem Two display programs are available gif2herc for hercules monochrome device +rem and gif2bgi for any device you have bgi driver for. See the docs for these +rem programs for more. +rem +rem set GIF_DISPLAY=gif2herc +set GIF_DISPLAY=gif2bgi -u c:\tc\bgi\ati\ati.2 +if not x%2 == x set GIF_DISPLAY = %2 + +@echo on + +gifwedge | %GIF_DISPLAY% + +gifbg -d tl -s 320 200 -c 255 255 255 -l 64 > bg1.gif +gifcomb %GIF_DIR%porsche.gif bg1.gif | %GIF_DISPLAY% +del bg1.gif + +text2gif -f 1 -s 7 -c 0 255 0 -t "Created using the IRIT solid modeler, Gershon Elber 1990" > credit.gif +gifasm %GIF_DIR%solid2.gif credit.gif | %GIF_DISPLAY% +del credit.gif + +gifhisto -t %GIF_DIR%cheryl.gif +gifhisto -b -s 200 512 %GIF_DIR%cheryl.gif | gifflip -l | %GIF_DISPLAY% + +gifflip -r %GIF_DIR%solid2.gif | gifrsize | %GIF_DISPLAY% + +gifinter %GIF_DIR%cheryl.gif | gifflip -x | %GIF_DISPLAY% + +gifbg -d "TL" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 0 0 > b1.gif +gifbg -d "BL" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 0 175 > b2.gif +gifbg -d "TR" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 320 0 > b3.gif +gifbg -d "BR" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 320 175 > b4.gif +gifasm b1.gif b2.gif b3.gif b4.gif > backgrnd.gif +%GIF_DISPLAY% backgrnd.gif +del b?.gif +del backgrnd.gif + +copy %GIF_DIR%solid2.gif s1.gif +gifrsize s1.gif > s2.gif +gifrsize s2.gif > s3.gif +gifrsize s3.gif > s4.gif +gifpos -i 320 0 s2.gif | gifinto s2.gif +gifpos -i 480 0 s3.gif | gifinto s3.gif +gifpos -i 560 0 s4.gif | gifinto s4.gif +gifasm s1.gif s2.gif s3.gif s4.gif > sall.gif +giftext sall.gif +%GIF_DISPLAY% sall.gif +gifrsize -s 0.45 sall.gif | %GIF_DISPLAY% +del s?.gif +del sall.gif + +gifpos -s 720 348 -i 400 148 %GIF_DIR%porsche.gif | %GIF_DISPLAY% + +gifrsize -S 300 600 %GIF_DIR%solid2.gif | %GIF_DISPLAY% + +gifinter %GIF_DIR%cheryl.gif | gifrsize | %GIF_DISPLAY% -z 2 + +rem This is broken since it overflow the 128 chars limit: +gifinter %GIF_DIR%cheryl.gif | gifclip -i 222 0 390 134 | gifpos -s 169 135 | gifrsize -s 2.0 > t.gif +%GIF_DISPLAY% t.gif +del t.gif + +gifrotat -a 45 %GIF_DIR%cheryl.gif | %GIF_DISPLAY% + +@echo off + +rem Remove these variables from current shell +Exit: + +set GIF_DIR= +set GIF_DISPLAY= + + + + diff --git a/G/TEST-UNX b/G/TEST-UNX new file mode 100644 index 0000000..ecb3562 --- /dev/null +++ b/G/TEST-UNX @@ -0,0 +1,71 @@ +#! /bin/csh -f +# +# Tests for the gif_lib utilities. +# Usage: +# test-unx [GIF_DIR] [display_prgm] +# +# This test assumes the gif_lib utilities are available from one of the +# path directorys, and that GIF_DIR is set (directly or through command line) +# to the directory holf these gif files: +# 1. solid2.gif +# 2. cheryl.gif +# 3. porsche.gif +# In addition, set GIF_DISPLAY ( directly or through command line) to the +# program to display gif files in our system. +# +# Gershon Elber, Feb 90. +# + +set GIF_DIR = ./pic +if ($1 != "") set GIF_DIR = $1 + +set GIF_DISPLAY = gif2iris +if ($2 != "") set GIF_DISPLAY = $2 + +gifbg -d tl -s 320 200 -c 255 255 255 -l 64 > bg1.gif +gifcomb $GIF_DIR/porsche.gif bg1.gif | $GIF_DISPLAY +rm -f bg1.gif + +text2gif -f 1 -s 7 -c 0 255 0 -t "Created using the IRIT solid modeler, Gershon Elber 1990" > credit.gif +gifasm $GIF_DIR/solid2.gif credit.gif | $GIF_DISPLAY +rm -f credit.gif + +gifhisto -t $GIF_DIR/cheryl.gif | sort -r | more +gifhisto -b -s 200 512 $GIF_DIR/cheryl.gif | gifflip -l | $GIF_DISPLAY + +gifflip -r $GIF_DIR/solid2.gif | gifrsize | $GIF_DISPLAY + +gifinter $GIF_DIR/cheryl.gif | gifflip -x | $GIF_DISPLAY + +gifbg -d "TL" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 0 0 > b1.gif +gifbg -d "BL" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 0 175 > b2.gif +gifbg -d "TR" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 320 0 > b3.gif +gifbg -d "BR" -s 320 175 -c 255 255 255 -l 64 | gifpos -s 640 350 -i 320 175 > b4.gif +gifasm b1.gif b2.gif b3.gif b4.gif > backgrnd.gif +$GIF_DISPLAY backgrnd.gif +rm -f b?.gif backgrnd.gif + +cp $GIF_DIR/solid2.gif s1.gif +gifrsize s1.gif > s2.gif +gifrsize s2.gif > s3.gif +gifrsize s3.gif > s4.gif +gifpos -i 320 0 s2.gif | gifinto s2.gif +gifpos -i 480 0 s3.gif | gifinto s3.gif +gifpos -i 560 0 s4.gif | gifinto s4.gif +gifasm s1.gif s2.gif s3.gif s4.gif > sall.gif +giftext sall.gif +$GIF_DISPLAY sall.gif +gifrsize -s 0.45 sall.gif | $GIF_DISPLAY +rm -f s?.gif sall.gif + +gifpos -s 720 348 -i 400 148 $GIF_DIR/porsche.gif | $GIF_DISPLAY + +gifrsize -S 800 600 $GIF_DIR/solid2.gif | $GIF_DISPLAY + +gifinter $GIF_DIR/cheryl.gif | gifrsize | $GIF_DISPLAY + +gifinter $GIF_DIR/cheryl.gif | gifclip -i 222 0 390 134 | gifpos -s 169 135 | gifrsize -s 2.0 | $GIF_DISPLAY + +gifrotat -a 45 $GIF_DIR/cheryl.gif | $GIF_DISPLAY + +Exit: diff --git a/G/UPDATE.NEW b/G/UPDATE.NEW new file mode 100644 index 0000000..29cca2b --- /dev/null +++ b/G/UPDATE.NEW @@ -0,0 +1,24 @@ +Version 1.2 +----------- +1. GIFFIX - a new tool to attempt and fix broken GIF images. Currently fix + images that has EOF prematurely by padding with the darkest color. +2. Make GIF2BGI display as much as it can considering the mem. avail. +3. Add -q flag to all tools for quite running scan line number mode. +4. Fix a (minor!?) bug in the GIF decoder when encountering code 4095. +5. New tools (RGB2GIF and GIF2RGB) to convert GIF to/from 24 bits RGB images. +6. New tool GIFROTAT to rotate a gif image by an arbitrary angle. +7. GifRSize was updated to resize by an arbitrary factor. + +Version 1.1 +----------- +1. GIF2BGI - a new utility to display GIF images using Borland's BGI drivers + (if you have one...) +2. TEXT2GIF - Converts plain text into GIF images. +3. GIF2IRIS - SGI4D display program for GIF images. +4. GIF_LIB naming convension has been modified to make sure it has unique + names (see gif_lib.h). +5. Support for SGI4D gl and X11 window grabbing has been added to the + library. SGI4D input is quantizied into 8 bits. + Also support for EGA/VGA devices has been added as well. + see Dev2gif.c module. +6. Support for the new gif89a format has been added. diff --git a/G/UTIL/GETARG.H b/G/UTIL/GETARG.H new file mode 100644 index 0000000..e09c59c --- /dev/null +++ b/G/UTIL/GETARG.H @@ -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 */ diff --git a/G/UTIL/GIF2BGI.C b/G/UTIL/GIF2BGI.C new file mode 100644 index 0000000..5e1c4fc --- /dev/null +++ b/G/UTIL/GIF2BGI.C @@ -0,0 +1,941 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to display GIF file using the BGI device indepedent routines * +* Options: * +* -q : quite printing mode. * +* -d BGI path : specify the directory where to look for bgi drivers. * +* -u BGIUserDriverName.Mode : use user driver instead of auto detection. * +* -z factor : zoom the pixels by the given factor. * +* -b : beeps disabled. * +* -h : on line help. * +* * +* In this file Screen refers to GIF file screen, while Device to BGI size. * +****************************************************************************** +* History: * +* 31 Jul 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2BGI" + +#define KEY_LEFT 256 /* Key Codes returned for operational keys */ +#define KEY_RIGHT 257 /* as return by the GetKey routine. */ +#define KEY_UP 258 +#define KEY_DOWN 259 +#define KEY_RETURN 260 +#define KEY_DELETE 261 +#define KEY_INSERT 262 +#define KEY_BSPACE 263 +#define KEY_ESC 264 +#define KEY_HOME 265 +#define KEY_END 266 +#define KEY_PGUP 267 +#define KEY_PGDN 268 + +#define SET_POSITION_RESET 0 /* Situations need positionings: */ +#define SET_POSITION_ZOOM_U 1 +#define SET_POSITION_ZOOM_D 2 +#define SET_POSITION_PAN 3 + +#define CURSOR_TEXT_X 120 + +#define BGI_USER_INSTALL 999 /* BGI User installed driver device. */ + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ + +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- d%-BGI|Directory!s u%-UserBGIDrv.Mode!s z%-ZoomFactor!d b%- h%- GifFile!*s"; +static char + *GifFileName, + *BGIPath = "", + *BGIUserDriverName = NULL; + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + ForeGround = 1, /* As close to white as possible. */ + BeepsDisabled = FALSE, + ZoomFactor = 1, + MaximumScreenHeight = 1, + BGIUserDriverMode = -1, + 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... */ +static GifColorType + *ColorMap; + +static int huge detectVGA(void); +static void BGIInstallUserDriver(char *BGIUserDriverNameMode); +static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile); +static void PrintSettingStatus(GifFileType *GifFile); +static void CPrintStr(char *Str, int y); +static void SetPosition(int Why, + int *ScreenLeft, int *ScreenTop, + int *DeviceLeft, int *DeviceTop, + int MoveX, int MoveY); +static void DrawScreen(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop); +static void DoCursorMode(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop); +static int MyKbHit(void); +static int MyGetCh(void); +static int GetKey(void); +static void Tone(int Frequency, int Time); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, k, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, + Count, ColorMapSize, GraphDriver, GraphMode, Sum, + HelpFlag = FALSE, + BGIPathFlag = FALSE, + BGIUserDriverFlag = FALSE, + ZoomFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension; + char Str[80], *BGIUserDriverNameMode, + **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + struct text_info TextInfo; /* So we can restore starting text mode. */ + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &BGIPathFlag, &BGIPath, + &BGIUserDriverFlag, &BGIUserDriverNameMode, + &ZoomFlag, &ZoomFactor, + &BeepsDisabled, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (BGIUserDriverFlag) { + /* Use the driver supplied by the user! */ + BGIInstallUserDriver(BGIUserDriverNameMode); + installuserdriver(BGIUserDriverName, detectVGA); + GraphDriver = BGI_USER_INSTALL; + } + else { + /* Sense type of display we have and attempt to load right driver. */ + detectgraph(&GraphDriver, &GraphMode); + if (GraphDriver < 0) + GIF_EXIT("BGI Auto detect: No graphics device detected."); + } + + /* Put in the following any graphic driver specific setup: */ + switch (GraphDriver) { + case CGA: + GraphMode = CGAHI; + break; + case EGA: + GraphMode = EGAHI; + break; + case EGA64: + GraphMode = EGA64HI; + break; + case EGAMONO: + GraphMode = EGAMONOHI; + break; + case HERCMONO: + GraphMode = HERCMONOHI; + break; + case VGA: + GraphMode = VGAHI; + break; + case BGI_USER_INSTALL: + GraphDriver = DETECT; + GraphMode = BGIUserDriverMode; + break; + default: + GIF_EXIT("Requested graphic device is not supported."); + break; + } + + if (NumFiles == 1) { + GifFileName = *FileName; + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + GifFileName = "Stdin"; + setmode(0, O_BINARY); + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + MaximumScreenHeight = GifFile -> SHeight - 1; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) { + if (i > 30) { + /* Free some memory for the BGI driver and auxilary. */ + for (j = 1; j < 28; j++) + free((char *) ScreenBuffer[i - j]); + MaximumScreenHeight = i - 28; + fprintf(stderr, "\n%s: Failed to allocate all memory required, last line %d.\n", + PROGRAM_NAME, MaximumScreenHeight); + break; + } + else + GIF_EXIT("Failed to allocate memory required, aborted."); + } + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + break; + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, + &ScreenBuffer[MIN(j, MaximumScreenHeight)][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++, Row++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[MIN(Row, MaximumScreenHeight)][Col], + Width) == GIF_ERROR) { + PrintGifError(); + MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel); + + gettextinfo(&TextInfo); /* Save current mode so we can recover. */ + + initgraph(&GraphDriver, &GraphMode, BGIPath); + if (graphresult() != grOk) /* Error occured during init. */ + GIF_EXIT("Graphics System Error, failed to initialize driver."); + + if (getmaxcolor() + 1 < ColorMapSize) { + sprintf(Str, "GIF Image color map (%d) is too big for device (%d).\n", + ColorMapSize, getmaxcolor() + 1); + closegraph(); + GIF_EXIT(Str); + } + + /* Initialize hardware pallete and also select fore/background color. */ + BackGround = ForeGround = 1; + Sum = ((int) ColorMap[1].Red) + + ((int) ColorMap[1].Green) + + ((int) ColorMap[1].Blue); + j = k = Sum; + for (i = 0; i < ColorMapSize; i++) { + setrgbpalette(i, ColorMap[i].Red >> 2, + ColorMap[i].Green >> 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; + } + } + + DeviceMaxX = getmaxx(); /* Read size of physical screen. */ + DeviceMaxY = getmaxy(); + ScreenWidth = GifFile -> SWidth; + ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight); + + Tone(500, 10); + DisplayScreen(ScreenBuffer, GifFile); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + closegraph(); + exit(-1); + } + + closegraph(); + + textmode(TextInfo.currmode); +} + +/**************************************************************************** +* Routine to be called for the user installed driver: * +****************************************************************************/ +static int huge detectVGA(void) +{ + return BGIUserDriverMode; +} + +/**************************************************************************** +* Routine to install the user BGI driver information. * +****************************************************************************/ +static void BGIInstallUserDriver(char *BGIUserDriverNameMode) +{ + char *p; + + if ((p = strrchr(BGIUserDriverNameMode, '/')) != NULL || + (p = strrchr(BGIUserDriverNameMode, '\\')) != NULL) { + p[0] = 0; + BGIPath = strdup(BGIUserDriverNameMode); + p++; + } + + p = strtok(p, "."); + BGIUserDriverName = strdup(p); + + p = strtok(NULL, "."); + if (sscanf(p, "%d", &BGIUserDriverMode) != 1 || BGIUserDriverName == NULL) + GIF_EXIT("User [-u] BGI specification has wrong format."); +} + +/****************************************************************************** +* Given the screen buffer, display it: * +* The following commands are available (case insensitive). * +* 1. Four arrow to move along the screen (only if ScreenBuffer > physical * +* screen in that direction. * +* 2. C - goto cursor mode - print current color & position in GIF screen * +* of the current pixel cursor is on. * +* 3. D - zoom out by factor of 2. * +* 4. R - redraw current image. * +* 5. S - Print Current status/options. * +* 6. U - zoom in by factor of 2. * +* 7. ' ' - stop drawing current image. * +* 8. ESC - to quit. * +******************************************************************************/ +static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile) +{ + int DeviceTop, DeviceLeft, /* Where ScreenBuffer is to mapped to ours. */ + ScreenTop, ScreenLeft, /* Porsion of ScreenBuffer to start display. */ + XPanning, YPanning, /* Amount to move using the arrows. */ + GetK, DrawIt = TRUE; + + XPanning = DeviceMaxX / 2; + YPanning = DeviceMaxY / 2; + + SetPosition(SET_POSITION_RESET, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + + do { + if (DrawIt && !MyKbHit()) { + DrawScreen(ScreenBuffer, ScreenLeft, ScreenTop, + DeviceLeft, DeviceTop); + Tone(2000, 200); + } + DrawIt = TRUE; + switch (GetK = GetKey()) { + case 'C': + DoCursorMode(ScreenBuffer, ScreenLeft, ScreenTop, + DeviceLeft, DeviceTop); + DrawIt = TRUE; + break; + case 'D': + if (ZoomFactor > 1) { + ZoomFactor >>= 1; + SetPosition(SET_POSITION_ZOOM_D, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + } + else { + Tone(1000, 100); + DrawIt = FALSE; + } + break; + case 'R': + break; + case 'S': + PrintSettingStatus(GifFile); + break; + case 'U': + if (ZoomFactor < 256) { + ZoomFactor <<= 1; + SetPosition(SET_POSITION_ZOOM_U, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + } + else { + Tone(1000, 100); + DrawIt = FALSE; + } + break; + case KEY_ESC: + break; + case KEY_LEFT: + SetPosition(SET_POSITION_PAN, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + -XPanning, 0); + break; + case KEY_RIGHT: + SetPosition(SET_POSITION_PAN, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + XPanning, 0); + break; + case KEY_UP: + SetPosition(SET_POSITION_PAN, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, -YPanning); + break; + case KEY_DOWN: + SetPosition(SET_POSITION_PAN, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, YPanning); + break; + default: + DrawIt = FALSE; + Tone(800, 100); + Tone(300, 200); + break; + } + } + while (GetK != KEY_ESC); +} + +/****************************************************************************** +* Routine to print (in text mode), current program status. * +******************************************************************************/ +static void PrintSettingStatus(GifFileType *GifFile) +{ + char s[80]; + + setcolor(ForeGround); + + CPrintStr(PROGRAM_NAME, 1); + + sprintf(s, "GIF File - %s.", GifFileName); + CPrintStr(s, 10); + + sprintf(s, "Gif Screen Size = [%d, %d]. Contains %d image(s).", + GifFile -> SWidth, GifFile -> SHeight, ImageNum); + CPrintStr(s, 20); + + if (GifFile -> SColorMap) + sprintf(s, + "Has Screen Color map of %d bits. BackGround = [%d, %d, %d].", + GifFile -> SBitsPerPixel, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Red, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Green, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Blue); + else + sprintf(s, "No Screen color map."); + CPrintStr(s, 30); + + if (GifFile -> IColorMap) + sprintf(s, "Has Image map of %d bits (last image). Image is %s.", + GifFile -> IBitsPerPixel, + (GifFile -> IInterlace ? "interlaced" : "non interlaced")); + else + sprintf(s, "No Image color map."); + CPrintStr(s, 40); + + CPrintStr("Press anything to continue:", 60); + MyGetCh(); +} + +/****************************************************************************** +* Routine to cprintf given string centered at given Y level, and attr: * +******************************************************************************/ +static void CPrintStr(char *Str, int y) +{ + setfillstyle(SOLID_FILL, BackGround); + bar(0, y, textwidth(Str) + 2, y + textheight(Str) + 2); + + setcolor(ForeGround); + outtextxy(1, y + 1, Str); +} + +/****************************************************************************** +* Routine to set the position of Screen in Device, and what porsion of the * +* screen should be visible: * +* MoveX, MoveY are the panning factors (if both zero - initialize). * +******************************************************************************/ +static void SetPosition(int Why, + int *ScreenLeft, int *ScreenTop, + int *DeviceLeft, int *DeviceTop, + int MoveX, int MoveY) +{ + + MoveX /= ZoomFactor; /* Make sure move move same amount independent. */ + MoveY /= ZoomFactor; /* of what ZommFactor is. */ + + /* Figure out position of GIF file in real device X axis: */ + if (ScreenWidth * ZoomFactor <= DeviceMaxX + 1) { + /* Device is big enough to hold all the image X axis: */ + *ScreenLeft = 0; + *DeviceLeft = (DeviceMaxX - ScreenWidth * ZoomFactor) / 2; + } + else { + /* Device is too small to hold all the image X axis: */ + switch (Why) { + case SET_POSITION_RESET: + *ScreenLeft = 0; + break; + case SET_POSITION_ZOOM_U: + *ScreenLeft += DeviceMaxX / (2 * ZoomFactor); + break; + case SET_POSITION_ZOOM_D: + *ScreenLeft -= DeviceMaxX / (4 * ZoomFactor); + break; + case SET_POSITION_PAN: + if (MoveX != 0) *ScreenLeft += MoveX; + break; + } + if (*ScreenLeft < 0) *ScreenLeft = 0; + if ((ScreenWidth - *ScreenLeft) * ZoomFactor < DeviceMaxX + 1) + *ScreenLeft = (ScreenWidth * ZoomFactor - + DeviceMaxX + 1) / ZoomFactor; + *DeviceLeft = 0; + } + + /* Figure out position of GIF file in real device Y axis: */ + if (ScreenHeight * ZoomFactor <= DeviceMaxY + 1) { + /* Device is big enough to hold all the image Y axis: */ + *ScreenTop = 0; + *DeviceTop = (DeviceMaxY - ScreenHeight * ZoomFactor) / 2; + } + else { + /* Device is too small to hold all the image Y axis: */ + switch (Why) { + case SET_POSITION_RESET: + *ScreenTop = 0; + break; + case SET_POSITION_ZOOM_U: + *ScreenTop += DeviceMaxY / (2 * ZoomFactor); + break; + case SET_POSITION_ZOOM_D: + *ScreenTop -= DeviceMaxY / (4 * ZoomFactor); + break; + case SET_POSITION_PAN: + if (MoveY != 0) *ScreenTop += MoveY; + break; + } + if (*ScreenTop < 0) *ScreenTop = 0; + if ((ScreenHeight - *ScreenTop) * ZoomFactor < DeviceMaxY + 1) + *ScreenTop = (ScreenHeight * ZoomFactor - + DeviceMaxY - 1) / ZoomFactor; + *DeviceTop = 0; + } + + /* Make sure the position is on Byte boundary (8 pixels per byte): */ + *DeviceLeft &= 0xfff8; +} + +/****************************************************************************** +* The real drawing of the image is performed here. Few things are taken into * +* account: * +* 1. The zoom factor. If > 1 each pixel is multiplied this amount vertically * +* and horizontally. * +* The image is drawn from ScreenBuffer ScreenTop/Left in the bottom/right * +* directions, onto the Device DeviceTop/Left in the bottom/right direction * +* Pressing space during drawing will abort this routine. * +******************************************************************************/ +static void DrawScreen(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop) +{ + int i, j, k, l, CountZoomJ, CountZoomI, + DeviceWidth, DeviceRight, ScreenBottom; + unsigned char *ImageBuffer, *p; + GifPixelType *Line; + + /* Make sure we start from scratch. Note cleardevice() uses color 0 even */ + /* if it may be non black. */ + cleardevice(); + + if (getmaxcolor() + 1 == 256) { + /* Optimize this case - one byte per pixel. */ + DeviceWidth = ScreenWidth * ZoomFactor; + if (DeviceWidth + DeviceLeft > DeviceMaxX) + DeviceWidth = DeviceMaxX - DeviceLeft; + DeviceRight = DeviceLeft + DeviceWidth - 1; + ScreenBottom = ScreenTop + ScreenHeight - 1; + + if ((ImageBuffer = malloc(imagesize(DeviceLeft, DeviceTop, + DeviceRight, DeviceTop))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + getimage(DeviceLeft, DeviceTop, DeviceRight, DeviceTop, ImageBuffer); + + for (k = DeviceTop; k < DeviceMaxY && ScreenTop <= ScreenBottom;) { + Line = ScreenBuffer[ScreenTop++]; + p = ImageBuffer + 4; /* point on first pixel in bitmap. */ + if (ZoomFactor == 1) + memcpy(p, &Line[ScreenLeft], DeviceWidth); + else { + for (i = 0, j = ScreenLeft, CountZoomI = ZoomFactor; + i < DeviceWidth; + i++) { + *p++ = Line[j]; + if (--CountZoomI == 0) { + CountZoomI = ZoomFactor; + j++; + } + } + } + + /* Abort drawing if space bar was pressed: */ + if (MyKbHit() && GetKey() == ' ') break; + + for (i = 0; i < ZoomFactor; i++) + putimage(DeviceLeft, k++, ImageBuffer, COPY_PUT); + } + + free((char *) ImageBuffer); + } + else { + for (CountZoomJ = ZoomFactor, j = ScreenTop, l = DeviceTop; + j < ScreenHeight && l <= DeviceMaxY; l++) { + Line = ScreenBuffer[j]; + + /* Abort drawing if space bar was pressed: */ + if (MyKbHit() && GetKey() == ' ') break; + + for (CountZoomI = ZoomFactor, i = ScreenLeft, k = DeviceLeft; + i < ScreenWidth && k <= DeviceMaxX;) { + putpixel(k++, l, Line[i]); + + if (!--CountZoomI) { + /* Go to next column: */ + i++; + CountZoomI = ZoomFactor; + } + } + + if (!--CountZoomJ) { + /* Go to next row: */ + j++; + CountZoomJ = ZoomFactor; + } + } + } +} + +/****************************************************************************** +* Walks along the current image, while printing pixel value and position. * +* 4 arrows may be used, and any other key will abort this operation * +******************************************************************************/ +static void DoCursorMode(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int DeviceLeft, int DeviceTop) +{ + int GetK, DeviceRight, DeviceBottom, x, y, Step; + GifPixelType Pixel; + char s[80]; + + DeviceRight = DeviceLeft + (ScreenWidth - ScreenLeft) * ZoomFactor; + if (DeviceRight > DeviceMaxX) DeviceRight = DeviceMaxX; + + DeviceBottom = DeviceTop + (ScreenHeight - ScreenTop) * ZoomFactor; + if (DeviceBottom > DeviceMaxY) DeviceBottom = DeviceMaxY; + + x = (DeviceLeft + DeviceRight) / 2; + y = (DeviceTop + DeviceBottom) / 2; + + setwritemode(XOR_PUT); + + while (TRUE) { + Pixel = ScreenBuffer[ScreenTop + (y - DeviceTop) / ZoomFactor] + [ScreenLeft + (x - DeviceLeft) / ZoomFactor]; + sprintf(s, "Color = %3d [%3d, %3d, %3d], X = %3d, Y = %3d", + Pixel, + ColorMap[Pixel].Red, + ColorMap[Pixel].Green, + ColorMap[Pixel].Blue, + (x - DeviceLeft) / ZoomFactor, + (y - DeviceTop) / ZoomFactor); + + setfillstyle(SOLID_FILL, BackGround); + bar(0, 0, textwidth(s) + 2, textheight(s) + 2); + + setcolor(ForeGround); + outtextxy(1, 1, s); + + line(0, y, DeviceMaxX, y); + line(x, 0, x, DeviceMaxY); + GetK = GetKey(); + line(0, y, DeviceMaxX, y); + line(x, 0, x, DeviceMaxY); + + Step = 10; + switch (GetK) { + case '1': + GetK = KEY_END; + break; + case '2': + GetK = KEY_DOWN; + break; + case '3': + GetK = KEY_PGDN; + break; + case '4': + GetK = KEY_LEFT; + break; + case '6': + GetK = KEY_RIGHT; + break; + case '7': + GetK = KEY_HOME; + break; + case '8': + GetK = KEY_UP; + break; + case '9': + GetK = KEY_PGUP; + break; + default: + Step = 1; + } + + switch (GetK) { + case KEY_LEFT: + x -= Step; + break; + case KEY_RIGHT: + x += Step; + break; + case KEY_UP: + y -= Step; + break; + case KEY_DOWN: + y += Step; + break; + case KEY_PGUP: + y -= Step; + x += Step; + break; + case KEY_PGDN: + y += Step; + x += Step; + break; + case KEY_HOME: + y -= Step; + x -= Step; + break; + case KEY_END: + y += Step; + x -= Step; + break; + default: + setwritemode(COPY_PUT); + return; + } + if (x < DeviceLeft) x = DeviceLeft; + if (x >= DeviceRight) x = DeviceRight; + if (y < DeviceTop) y = DeviceTop; + if (y >= DeviceBottom) y = DeviceBottom; + } +} + +/****************************************************************************** +* Return non zero value if at list one character exists in keyboard queue. * +* This routine emulates kbhit() which do uses stdin and useless for us. * +******************************************************************************/ +static int MyKbHit(void) +{ + return bioskey(1); +} + +/****************************************************************************** +* Get a key from keyboard directly (bypass stdin as we might redirect it). * +* This routine emulates getch() which do uses stdin and useless for us. * +******************************************************************************/ +static int MyGetCh(void) +{ + static int Extended = 0; + int c; + + if (Extended) { + c = Extended; + Extended = 0; + return c; + } + else { + c = bioskey(0); + if (c & 0x0ff) + return c; + else { + Extended = c >> 8; + return 0; + } + } +} + +/****************************************************************************** +* Get a key from keyboard, and translating operational keys into special * +* codes (>255). Lower case characters are upercased. * +******************************************************************************/ +static int GetKey(void) +{ + char c; + + while (TRUE) switch (c = MyGetCh()) { + case 0: /* Extended code - get the next extended char. */ + switch (MyGetCh()) { + case 75: return KEY_LEFT; + case 77: return KEY_RIGHT; + case 72: return KEY_UP; + case 80: return KEY_DOWN; + case 71: return KEY_HOME; + case 79: return KEY_END; + case 73: return KEY_PGUP; + case 81: return KEY_PGDN; + case 83: return KEY_DELETE; + case 82: return KEY_INSERT; + } + break; + case 8: + return KEY_BSPACE; + case 10: + case 13: + return KEY_RETURN; + case 27: + return KEY_ESC; + default: + if (isprint(c)) { + if (islower(c)) + return toupper(c); + else + return c; + } + else { + Tone(800, 100); + Tone(300, 200); + } + } +} + +/****************************************************************************** +* Routine to make some sound with given Frequency, Time milliseconds: * +******************************************************************************/ +static void Tone(int Frequency, int Time) +{ + if (BeepsDisabled) return; + + sound(Frequency); + delay(Time); + nosound(); +} diff --git a/G/UTIL/GIF2EPSN.C b/G/UTIL/GIF2EPSN.C new file mode 100644 index 0000000..38b35a4 --- /dev/null +++ b/G/UTIL/GIF2EPSN.C @@ -0,0 +1,590 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to dump GIF file into EPSON type printers * +* Options: * +* -q : quite printing mode. * +* -d factor : use dithering of matrix of size factor by factor. * +* -t level : set the threshold level of white in the result (0..100). * +* -m mapping : methods for mapping the 24bits colors into 1 BW bit. * +* -p printer : specify printer to print to (lpt1: by default). * +* -n : nice mode : uses double density to achieve better quality. * +* -i : invert the image. * +* -h : on line help. * +****************************************************************************** +* History: * +* 15 Jul 89 - Version 1.0 by Gershon Elber. * +* 22 Dec 89 - Fix problems with const strings been modified (Version 1.1). * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2Epsn" + +#define C2BW_BACK_GROUND 0 /*Methods to map 24bits Colors to 1 BW bit.*/ +#define C2BW_GREY_LEVELS 1 +#define C2BW_DITHER 2 +#define C2BW_NUM_METHODS 3 /* Always hold # of methods. */ + +#define DEFAULT_THRESHOLD 5000 /* Color -> BW threshold level. */ + +#define DITHER_MIN_MATRIX 2 +#define DITHER_MAX_MATRIX 4 + +/* The epson specific are defined here: */ +#define EPSON_WIDTH 80 /* 80 char per line. */ +#define EPSON_PIXEL_2_CHAR 8 /* 8 pixels per char, in REG_DENSITY. */ + +#define EPSON_ESC "\033" /* Actually regular escape char. */ +#define EPSON_RESET "\033@" /* Reset the printer. */ +#define EPSON_VERTICAL_SPACE "\033A\010" /* 8/72 inch vertically. */ +#define EPSON_REG_DENSITY "\033K" /* 640 pixels per 7.5" (line). */ +#define EPSON_DUAL_DENSITY "\033L" /* 1280 pixels per 7.5" (line). */ + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2Epsn q%- d%-DitherSize!d t%-BWThreshold!d m%-Mapping!d i%- n%- p%-PrinterName!s h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- d%-DitherSize!d t%-BWThreshold!d m%-Mapping!d i%- n%- p%-PrinterName!s h%- GifFile!*s"; +#endif /* SYSV */ + +static char + *PrinterName = NULL; +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + DitherSize = 2, DitherFlag = FALSE, + BWThresholdFlag = FALSE, Threshold, + BWThreshold = DEFAULT_THRESHOLD, /* Color -> BW mapping threshold. */ + Mapping, MappingFlag = FALSE, + InvertFlag = FALSE, + NiceFlag = FALSE, + PrinterFlag = FALSE, + HelpFlag = FALSE, + ColorToBWMapping = C2BW_BACK_GROUND, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static GifColorType + *ColorMap; + +static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row, + int RowSize, GifRowType *DitherBuffer); +static void DumpScreen2Epsn(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); +static void PutString(FILE *Prt, int DirectPrint, char *Str, int Len); +static void PutString2(FILE *Prt, int DirectPrint, char *Str, int Len); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &DitherFlag, &DitherSize, + &BWThresholdFlag, &Threshold, + &MappingFlag, &Mapping, &InvertFlag, + &NiceFlag, &PrinterFlag, &PrinterName, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (!PrinterFlag) PrinterName = ""; + + if (DitherFlag) { + /* Make sure we are o.k.: */ + if (DitherSize > DITHER_MAX_MATRIX) DitherSize = DITHER_MAX_MATRIX; + if (DitherSize < DITHER_MIN_MATRIX) DitherSize = DITHER_MAX_MATRIX; + } + + /* As Threshold is in [0..100] range and BWThreshold is [0..25500]: */ + if (BWThresholdFlag) { + if (Threshold > 100 || Threshold < 0) + GIF_EXIT("Threshold not in 0..100 percent."); + BWThreshold = Threshold * 255; + if (BWThreshold == 0) BWThreshold = 1; /* Overcome divide by zero! */ + } + + /* No message is emitted, but mapping method is clipped to exists method.*/ + if (MappingFlag) ColorToBWMapping = Mapping % C2BW_NUM_METHODS; + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, andset their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted.\n"); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + DumpScreen2Epsn(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/***************************************************************************** +* Routine to evaluate dithered scanlines out of given ones, using Size * +* dithering matrix, starting from Row. The given scanlines are NOT modified. * +*****************************************************************************/ +static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row, + int RowSize, GifRowType *DitherBuffer) +{ + static char Dither2[2][2] = { /* See Foley & Van Dam pp. 597-601. */ + { 1, 3 }, + { 4, 2 } + }; + static char Dither3[3][3] = { + { 7, 9, 5 }, + { 2, 1, 4 }, + { 6, 3, 8 } + }; + static char Dither4[4][4] = { + { 1, 9, 3, 11 }, + { 13, 5, 15, 7 }, + { 4, 12, 2, 10 }, + { 16, 8, 14, 6 } + }; + int i, j, k, Level; + long Intensity; + GifColorType *ColorMapEntry; + + /* Scan the Rows (Size rows) evaluate intensity every Size pixel and use */ + /* the dither matrix to set the dithered result; */ + for (i = 0; i <= RowSize - DitherSize; i += DitherSize) { + Intensity = 0; + for (j = Row; j < Row + DitherSize; j++) + for (k = 0; k < DitherSize; k++) { + ColorMapEntry = &ColorMap[ScreenBuffer[j][i+k]]; + Intensity += 30 * ((int) ColorMapEntry->Red) + + 59 * ((int) ColorMapEntry->Green) + + 11 * ((int) ColorMapEntry->Blue); + } + + /* Find the intensity level (between 0 and Size^2) of our matrix: */ + /* Expression is "Intensity * BWThreshold / (25500 * DefThresh)" */ + /* but to prevent from overflow in the long evaluation we do this: */ + Level = ((Intensity / 2550) * ((long) DEFAULT_THRESHOLD) / + (((long) BWThreshold) * 10)); + switch (DitherSize) { + case 2: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither2[j][k] <= Level; + break; + case 3: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither3[j][k] <= Level; + break; + case 4: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither4[j][k] <= Level; + break; + } + } +} + +/****************************************************************************** +* The real dumping routine. Few things are taken into account: * +* 1. The Nice flag. If TRUE each pixel is printed twice in double density. * +* 2. The Invert flag. If TRUE each pixel before drawn is inverted. * +* 3. The rendering mode and dither matrix flag if dithering is selected. * +* The image is drawn from ScreenBuffer ScreenTop/Left in the bottom/right * +* directions. * +* Unfortunatelly, there is a BUG in DOS that does not handle ctrl-Z * +* correctly if we open lptx: device in binary mode (should treat it as any * +* other char). Therefore I had to write to it directly using biosprint. I * +* dont like it either, and if you have better way to do it, let me know. * +******************************************************************************/ +static void DumpScreen2Epsn(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + int i, j, p, Size, LeftCWidth, Len, DirectPrint = 0, + DitheredLinesLeft = 0, DitheredLinesCount = 0, MapInvert[2]; + char LinePrefixLen[2]; /* Length of scan line. */ + GifByteType *EpsonBuffer; + GifPixelType *Line; + GifRowType *DitherBuffer; + GifColorType *ColorMapEntry; + FILE *Prt = NULL; + +#ifdef __MSDOS__ + for (i = 0; i < strlen(PrinterName); i++) + if (islower(PrinterName[i])) + PrinterName[i] = toupper(PrinterName[i]); + + if (strcmp(PrinterName, "LPT1") == 0 || + strcmp(PrinterName, "PRN") == 0) + DirectPrint = 1; + else if (strcmp(PrinterName, "LPT2") == 0) + DirectPrint = 2; + else if (strcmp(PrinterName, "LPT3") == 0) + DirectPrint = 3; +#endif /* __MSDOS__ */ + + if (!DirectPrint) { +#ifdef __MSDOS__ + if (strlen(PrinterName) == 0) { + setmode(1, O_BINARY); /* Make sure it is in binary mode. */ + Prt = stdout; + } + else if ((Prt = fopen(PrinterName, "wb")) == NULL || + setvbuf(Prt, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE)) +#else + if (strlen(PrinterName) == 0) + Prt = stdout; + else if ((Prt = fopen(PrinterName, "w")) == NULL) +#endif /* __MSDOS__ */ + GIF_EXIT("Failed to open output (printer) file."); + } + + if ((EpsonBuffer = (GifByteType *) malloc(ScreenWidth)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + /* Allocate the buffer to save the dithered information. */ + if (ColorToBWMapping == C2BW_DITHER) { + if ((DitherBuffer = (GifRowType *) + malloc(DITHER_MAX_MATRIX * sizeof(GifRowType *))) != NULL) { + Size = ScreenWidth * sizeof(GifPixelType); /* Size of one row. */ + for (i = 0; i < DITHER_MAX_MATRIX; i++) { + if ((DitherBuffer[i] = (GifRowType) malloc(Size)) == NULL) { + DitherBuffer = NULL; + break; + } + } + } + if (DitherBuffer == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + } + else + DitherBuffer = NULL; + + /* Reset the printer, and make sure no space between adjacent lines: */ + PutString(Prt, DirectPrint, EPSON_RESET, 2); + PutString(Prt, DirectPrint, EPSON_VERTICAL_SPACE, 3); + + /* Prepar left spacing to begin with, so image will be in the middle. */ + LeftCWidth = (EPSON_WIDTH - (ScreenWidth / EPSON_PIXEL_2_CHAR)) / 2; + + if (InvertFlag) { /* Make the inversion as fast a possible. */ + MapInvert[0] = 1; + MapInvert[1] = 0; + } + else { + MapInvert[0] = 0; + MapInvert[1] = 1; + } + + for (i = 0, p = 0; i < ScreenHeight; i++, p++) { + GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); + Line = ScreenBuffer[i]; + + /* If 8 lines were accumulated in printer buffer - dump them out. */ + if (p == 8) { + for (Len = ScreenWidth-1; Len >= 0; Len--) + if (EpsonBuffer[Len]) break; + + /* Only in case this line is not empty: */ + if (Len++ >= 0) { + /* Make the left space, so image will be centered: */ + for (j = 0; j < LeftCWidth; j++) + PutString(Prt, DirectPrint, " ", 1); + + /* Full printer line is ready to be dumped - send it out: */ + if (NiceFlag) { + PutString(Prt, DirectPrint, EPSON_DUAL_DENSITY, 2); + LinePrefixLen[0] = (Len * 2) % 256; + LinePrefixLen[1] = (Len * 2) / 256; + PutString(Prt, DirectPrint, LinePrefixLen, 2); + PutString2(Prt, DirectPrint, (char *) EpsonBuffer, Len); + } + else { + PutString(Prt, DirectPrint, EPSON_REG_DENSITY, 2); + LinePrefixLen[0] = Len % 256; + LinePrefixLen[1] = Len / 256; + PutString(Prt, DirectPrint, LinePrefixLen, 2); + PutString(Prt, DirectPrint, (char *) EpsonBuffer, Len); + } + } + PutString(Prt, DirectPrint, "\015\012", 2); + p = 0; + } + + /* We decide right here what method to map Colors to BW so the inner */ + /* loop will be independent of it (and therefore faster): */ + switch(ColorToBWMapping) { + case C2BW_BACK_GROUND: + for (j = 0; j < ScreenWidth; j++) + EpsonBuffer[j] = (EpsonBuffer[j] << 1) + + MapInvert[Line[j] != BackGround]; + break; + case C2BW_GREY_LEVELS: + for (j = 0; j < ScreenWidth; j++) { + ColorMapEntry = &ColorMap[Line[j]]; + /* For the transformation from RGB to BW, see Folley & */ + /* Van Dam pp 613: The Y channel is the BW we need: */ + /* As colors are 255 maximum, the result can be up to */ + /* 25500 which is still in range of our 16 bits integers */ + EpsonBuffer[j] = (EpsonBuffer[j] << 1) + + MapInvert[(30 * (int) ColorMapEntry->Red) + + 59 * ((int) ColorMapEntry->Green) + + 11 * ((int) ColorMapEntry->Blue) > + BWThreshold]; + } + break; + case C2BW_DITHER: + if (DitheredLinesLeft-- == 0) { + EvalDitheredScanline(ScreenBuffer, + (i < ScreenHeight - DitherSize ? i : + ScreenHeight - DitherSize), + ScreenWidth, DitherBuffer); + DitheredLinesLeft = DitherSize - 1; + DitheredLinesCount = 0; + } + Line = DitherBuffer[DitheredLinesCount++]; + for (j = 0; j < ScreenWidth; j++) + EpsonBuffer[j] = (EpsonBuffer[j] << 1) + + MapInvert[Line[j]]; + break; + } + } + + /* If buffer in incomplete - complete it and dump it out: */ + if (p != 0) { + for (Len = ScreenWidth - 1; Len >= 0; Len--) + if (EpsonBuffer[Len]) break; + if (Len++ >= 0) { + i = 8 - p; /* Amount to shift. */ + for (j = 0; j < ScreenWidth; j++) EpsonBuffer[j] <<= i; + + /* Make the left space, so image will be centered: */ + for (j = 0; j < LeftCWidth; j++) + PutString(Prt, DirectPrint, " ", 1); + + if (NiceFlag) { + PutString(Prt, DirectPrint, EPSON_DUAL_DENSITY, 2); + LinePrefixLen[0] = (Len * 2) % 256; + LinePrefixLen[1] = (Len * 2) / 256; + PutString(Prt, DirectPrint, LinePrefixLen, 2); + PutString2(Prt, DirectPrint, (char *) EpsonBuffer, Len); + } + else { + PutString(Prt, DirectPrint, EPSON_REG_DENSITY, 2); + LinePrefixLen[0] = Len % 256; + LinePrefixLen[1] = Len / 256; + PutString(Prt, DirectPrint, LinePrefixLen, 2); + PutString(Prt, DirectPrint, (char *) EpsonBuffer, Len); + } + } + PutString(Prt, DirectPrint, "\015\012", 2); + } + + fclose(Prt); +} + +/****************************************************************************** +* Dumps the string of given length, to Prt. No char in Str has special * +* meaning, and even zero (NULL) chars are dumped. * +* If however DirectPrint is non zero, string is dumped to specifed lpt port. * +******************************************************************************/ +static void PutString(FILE *Prt, int DirectPrint, char *Str, int Len) +{ + int i; + + if (DirectPrint) { +#ifdef __MSDOS__ + for (i = 0; i < Len; i++) biosprint(0, Str[i], DirectPrint - 1); +#else + GIF_EXIT("Can not print directly to a printer if not MSDOS."); +#endif /* __MSDOS__ */ + } + else + for (i = 0; i < Len; i++) fputc(Str[i], Prt); +} + +/****************************************************************************** +* Dumps the string of given length, to Prt. No char in Str has special * +* meaning, and even zero (NULL) chars are dumped. Every char is dumped twice. * +* If however DirectPrint is non zero, string is dumped to specifed lpt port. * +******************************************************************************/ +static void PutString2(FILE *Prt, int DirectPrint, char *Str, int Len) +{ + int i; + + if (DirectPrint) { +#ifdef __MSDOS__ + for (i = 0; i < Len; i++) { + biosprint(0, Str[i], DirectPrint - 1); + biosprint(0, Str[i], DirectPrint - 1); + } +#else + GIF_EXIT("Can not print directly to a printer if not MSDOS."); +#endif /* __MSDOS__ */ + } + else + for (i = 0; i < Len; i++) { + fputc(Str[i], Prt); + fputc(Str[i], Prt); + } +} diff --git a/G/UTIL/GIF2HERC.C b/G/UTIL/GIF2HERC.C new file mode 100644 index 0000000..46d04e2 --- /dev/null +++ b/G/UTIL/GIF2HERC.C @@ -0,0 +1,1108 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to display GIF file on hercules device * +* Options: * +* -q : quite printing mode. * +* -z factor : zoom the pixels by the given factor. * +* -t level : set the threshold level of white in the result (0..100). * +* -m mapping : methods for mapping the 24bits colors into 1 BW bit. * +* -i : invert the image. * +* -b : beeps disabled. * +* -h : on line help. * +* * +* This program uses TC2.0 hercules graphic driver. * +* In this file Screen refers to GIF file screen, while Device to Hercules. * +****************************************************************************** +* History: * +* 1 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2Herc" + +#define KEY_LEFT 256 /* Key Codes returned for operational keys */ +#define KEY_RIGHT 257 /* as return by the GetKey routine. */ +#define KEY_UP 258 +#define KEY_DOWN 259 +#define KEY_RETURN 260 +#define KEY_DELETE 261 +#define KEY_INSERT 262 +#define KEY_BSPACE 263 +#define KEY_ESC 264 +#define KEY_HOME 265 +#define KEY_END 266 +#define KEY_PGUP 267 +#define KEY_PGDN 268 + +#define C2BW_BACK_GROUND 0 /*Methods to map 24bits Colors to 1 BW bit.*/ +#define C2BW_GREY_LEVELS 1 +#define C2BW_DITHER 2 +#define C2BW_NUM_METHODS 3 /* Always hold # of methods. */ + +#define DEFAULT_THRESHOLD 5000 /* Color -> BW threshold level. */ +#define INCREMENT_THRESHOLD 1000 + +#define DITHER_MIN_MATRIX 2 +#define DITHER_MAX_MATRIX 4 + +#define NORMAL_ATTR 0x07 /* Text attributes. */ +#define INVERSE_ATTR 0x70 +#define BLINK_ATTR 0x90 + +#define SET_POSITION_RESET 0 /* Situations need positionings: */ +#define SET_POSITION_ZOOM_U 1 +#define SET_POSITION_ZOOM_D 2 +#define SET_POSITION_PAN 3 + +#define DEVICE_BASE 0xb000 /* Hercules frame buffer base. */ +#define DEVICE_PAGE0 0xb000 +#define DEVICE_PAGE1 0xb800 +#define HERC_MAX_X 719 +#define HERC_MAX_Y 347 + +#define CURSOR_TEXT_X 120 + +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ + +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- d%-DitherSize!d z%-ZoomFactor!d t%-BWThreshold!d m%-Mapping!d i%- b%- h%- GifFile!*s"; +static char + *GifFileName; +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + BeepsDisabled = FALSE, + DitherSize = 2, DitherFlag = FALSE, + ZoomFactor = 1, ZoomFlag = FALSE, + BWThresholdFlag = FALSE, Threshold, + BWThreshold = DEFAULT_THRESHOLD, /* Color -> BW mapping threshold. */ + Mapping, MappingFlag = FALSE, + InvertFlag = FALSE, + HelpFlag = FALSE, + ColorToBWMapping = C2BW_BACK_GROUND, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static GifColorType + *ColorMap; + + +static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile); +static void PrintSettingStatus(GifFileType *GifFile, GifRowType *DitherBuffer); +static void CPrintStr(char *Str, int y, int attr); +static void SetPositon(int Why, + int ScreenWidth, int ScreenHeight, + int DeviceMaxX, int DeviceMaxY, + int *ScreenLeft, int *ScreenTop, + int *DeviceLeft, int *DeviceTop, + int MoveX, int MoveY); +static void ClearGraphDevice(void); +static void OpenGraphDevice(void); +static void CloseGraphDevice(void); +static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row, + int RowSize, GifRowType *DitherBuffer); +static void DrawScreen(GifRowType *ScreenBuffer, GifRowType *DitherBuffer, + int DeviceTop, int DeviceLeft, int DeviceMaxX, int DeviceMaxY, + int ScreenTop, int ScreenLeft, int ScreenWidth, int ScreenHeight); +static void DoCursorMode(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int ScreenWidth, int ScreenHeight, + int DeviceLeft, int DeviceTop); +static int MyKbHit(void); +static int MyGetCh(void); +static int GetKey(void); +static void Tone(int Frequency, int Time); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &DitherFlag, &DitherSize, + &ZoomFlag, &ZoomFactor, &BWThresholdFlag, + &Threshold, &MappingFlag, &Mapping, &InvertFlag, + &BeepsDisabled, &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (DitherFlag) { + /* Make sure we are o.k.: */ + if (DitherSize > DITHER_MAX_MATRIX) DitherSize = DITHER_MAX_MATRIX; + if (DitherSize < DITHER_MIN_MATRIX) DitherSize = DITHER_MAX_MATRIX; + } + + /* As Threshold is in [0..100] range and BWThreshold is [0..25500]: */ + if (BWThresholdFlag) { + if (Threshold > 100 || Threshold < 0) + GIF_EXIT("Threshold not in 0..100 percent."); + BWThreshold = Threshold * 255; + if (BWThreshold == 0) BWThreshold = 1; /* Overcome divide by zero! */ + } + + /* No message is emitted, but mapping method is clipped to exists method.*/ + if (MappingFlag) ColorToBWMapping = Mapping % C2BW_NUM_METHODS; + + if (NumFiles == 1) { + GifFileName = *FileName; + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + GifFileName = "Stdin"; + setmode(0, O_BINARY); + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, andset their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + Tone(500, 10); + DisplayScreen(ScreenBuffer, GifFile); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/****************************************************************************** +* Given the screen buffer, display it: * +* The following commands are available (case insensitive). * +* 1. Four arrow to move along the screen (only if ScreenBuffer > physical * +* screen in that direction. * +* 2. C - goto cursor mode - print current color & position in GIF screen * +* of the current pixel cursor is on. * +* 3. D - zoom out by factor of 2. * +* 4. H - halftoning dithering matrix resize. * +* 5. I - invert the image. * +* 6. M - toggles method of Color -> BW mapping. * +* 7. R - redraw current image. * +* 8. S - Print Current status/options. * +* 9. U - zoom in by factor of 2. * +* 10. ' ' - stop drawing current image. * +* 11. ESC - to quit. * +******************************************************************************/ +static void DisplayScreen(GifRowType *ScreenBuffer, GifFileType *GifFile) +{ + int i, j, Size, + DeviceTop, DeviceLeft, /* Where ScreenBuffer is to mapped to ours. */ + ScreenTop, ScreenLeft, /* Porsion of ScreenBuffer to start display. */ + DeviceMaxX, DeviceMaxY, /* Physical device dimensions. */ + XPanning, YPanning, /* Amount to move using the arrows. */ + GetK, DrawIt = TRUE; + GifRowType *DitherBuffer; /* Used to save dithered pixel scanned. */ + + OpenGraphDevice(); + DeviceMaxX = HERC_MAX_X; /* Read size of physical screen. */ + DeviceMaxY = HERC_MAX_Y; + + XPanning = DeviceMaxX / 2; + YPanning = DeviceMaxY / 2; + + SetPositon(SET_POSITION_RESET, GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + + /* Allocate the buffer to save the dithered information. If fails to */ + /* allocate, set it to NULL, and no dithering will take place. */ + if ((DitherBuffer = (GifRowType *) + malloc(DITHER_MAX_MATRIX * sizeof(GifRowType *))) != NULL) { + Size = GifFile -> SWidth * sizeof(GifPixelType); /* Size of one row. */ + for (i = 0; i < DITHER_MAX_MATRIX; i++) { + if ((DitherBuffer[i] = (GifRowType) malloc(Size)) == NULL) { + for (j = 0; j < i; j++) free((char *) DitherBuffer[i]); + free((char *) DitherBuffer); + DitherBuffer = NULL; + break; + } + } + } + if (DitherBuffer == NULL) { + Tone(300, 100); + Tone(100, 300); + } + + do { + if (DrawIt && !MyKbHit()) { + DrawScreen(ScreenBuffer, DitherBuffer, + DeviceTop, DeviceLeft, DeviceMaxX, DeviceMaxY, + ScreenTop, ScreenLeft, GifFile -> SWidth, GifFile -> SHeight); + Tone(2000, 200); + } + DrawIt = TRUE; + switch (GetK = GetKey()) { + case 'C': + DoCursorMode(ScreenBuffer, ScreenLeft, ScreenTop, + GifFile -> SWidth, GifFile -> SHeight, + DeviceLeft, DeviceTop); + DrawIt = FALSE; + break; + case 'D': + if (ZoomFactor > 1) { + ZoomFactor >>= 1; + SetPositon(SET_POSITION_ZOOM_D, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + } + else { + Tone(1000, 100); + DrawIt = FALSE; + } + break; + case 'H': + if (++DitherSize > DITHER_MAX_MATRIX) + DitherSize = DITHER_MIN_MATRIX; + break; + case 'I': + InvertFlag = !InvertFlag; + break; + case 'M': + ColorToBWMapping = (ColorToBWMapping + 1) % C2BW_NUM_METHODS; + + break; + case 'R': + break; + case 'S': + PrintSettingStatus(GifFile, DitherBuffer); + break; + case 'U': + if (ZoomFactor < 256) { + ZoomFactor <<= 1; + SetPositon(SET_POSITION_ZOOM_U, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, 0); + } + else { + Tone(1000, 100); + DrawIt = FALSE; + } + break; + case KEY_ESC: + break; + case KEY_LEFT: + SetPositon(SET_POSITION_PAN, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + -XPanning, 0); + break; + case KEY_RIGHT: + SetPositon(SET_POSITION_PAN, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + XPanning, 0); + break; + case KEY_UP: + SetPositon(SET_POSITION_PAN, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, -YPanning); + break; + case KEY_DOWN: + SetPositon(SET_POSITION_PAN, + GifFile -> SWidth, GifFile -> SHeight, + DeviceMaxX, DeviceMaxY, + &ScreenLeft, &ScreenTop, + &DeviceLeft, &DeviceTop, + 0, YPanning); + break; + case KEY_DELETE: + BWThreshold += INCREMENT_THRESHOLD; + if (BWThreshold == 0) BWThreshold = 1; + break; + case KEY_INSERT: + BWThreshold -= INCREMENT_THRESHOLD; + if (BWThreshold == 0) BWThreshold = 1; + break; + default: + DrawIt = FALSE; + Tone(800, 100); + Tone(300, 200); + break; + } + } + while (GetK != KEY_ESC); + + CloseGraphDevice(); +} + +/****************************************************************************** +* Routine to print (in text mode), current program status. * +******************************************************************************/ +static void PrintSettingStatus(GifFileType *GifFile, GifRowType *DitherBuffer) +{ + char s[80]; + + CloseGraphDevice(); + + CPrintStr(PROGRAM_NAME, 1, INVERSE_ATTR); + + sprintf(s, "GIF File - %s", GifFileName); + CPrintStr(s, 3, NORMAL_ATTR); + + sprintf(s, "Gif Screen Size = [%d, %d]. Contains %d image(s).", + GifFile -> SWidth, GifFile -> SHeight, ImageNum); + CPrintStr(s, 5, NORMAL_ATTR); + + if (GifFile -> SColorMap) + sprintf(s, + "Has Screen Color map of %d bits. BackGround = [%d, %d, %d]", + GifFile -> SBitsPerPixel, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Red, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Green, + GifFile -> SColorMap[GifFile -> SBackGroundColor].Blue); + else + sprintf(s, "No Screen color map."); + CPrintStr(s, 7, NORMAL_ATTR); + + if (GifFile -> IColorMap) + sprintf(s, "Has Image map of %d bits (last image). Image is %s.", + GifFile -> IBitsPerPixel, + (GifFile -> IInterlace ? "interlaced" : "non interlaced")); + else + sprintf(s, "No Image color map."); + CPrintStr(s, 9, NORMAL_ATTR); + + sprintf(s, "Color to BW threshold level - %d%%.\n", BWThreshold / 255); + CPrintStr(s, 11, NORMAL_ATTR); + + CPrintStr("Color To BW mapping:", 15, NORMAL_ATTR); + switch(ColorToBWMapping) { + case C2BW_BACK_GROUND: + CPrintStr("Color != BackGround", 16, NORMAL_ATTR); + break; + case C2BW_GREY_LEVELS: + CPrintStr(".3 * R + .59 * G + .11 * B > threshold", 16, + NORMAL_ATTR); + break; + case C2BW_DITHER: + sprintf(s, ".3 * R + .59 * G + .11 * B dithered (Size = %d).", + DitherSize); + CPrintStr(s, 16, NORMAL_ATTR); + break; + } + + sprintf(s, "Dither Buffer %s (Size = %d), Zoom = %d.", + DitherBuffer ? "allocated succesfully" : "not allocated (failed)", + DitherSize, ZoomFactor); + + CPrintStr(s, 18, NORMAL_ATTR); + + CPrintStr("Press anything to continue:", 23, BLINK_ATTR); + MyGetCh(); + + OpenGraphDevice(); +} + +/****************************************************************************** +* Routine to cprintf given string centered at given Y level, and attr: * +******************************************************************************/ +static void CPrintStr(char *Str, int y, int attr) +{ + gotoxy(40 - (strlen(Str) + 1) / 2, y); + textattr(attr); + cputs(Str); +} + +/****************************************************************************** +* Routine to set the position of Screen in Device, and what porsion of the * +* screen should be visible: * +* MoveX, MoveY are the panning factors (if both zero - initialize). * +******************************************************************************/ +static void SetPositon(int Why, + int ScreenWidth, int ScreenHeight, + int DeviceMaxX, int DeviceMaxY, + int *ScreenLeft, int *ScreenTop, + int *DeviceLeft, int *DeviceTop, + int MoveX, int MoveY) +{ + + MoveX /= ZoomFactor; /* Make sure move same amount independent */ + MoveY /= ZoomFactor; /* of what ZoomFactor is. */ + + /* Figure out position of GIF file in real device X axis: */ + if (ScreenWidth * ZoomFactor <= DeviceMaxX + 1) { + /* Device is big enough to hold all the image X axis: */ + *ScreenLeft = 0; + *DeviceLeft = (DeviceMaxX - ScreenWidth * ZoomFactor) / 2; + } + else { + /* Device is too small to hold all the image X axis: */ + switch (Why) { + case SET_POSITION_RESET: + *ScreenLeft = 0; + break; + case SET_POSITION_ZOOM_U: + *ScreenLeft += DeviceMaxX / (2 * ZoomFactor); + break; + case SET_POSITION_ZOOM_D: + *ScreenLeft -= DeviceMaxX / (4 * ZoomFactor); + break; + case SET_POSITION_PAN: + if (MoveX != 0) *ScreenLeft += MoveX; + break; + } + if (*ScreenLeft < 0) *ScreenLeft = 0; + if ((ScreenWidth - *ScreenLeft) * ZoomFactor < DeviceMaxX + 1) + *ScreenLeft = (ScreenWidth * ZoomFactor - + DeviceMaxX + 1) / ZoomFactor; + *DeviceLeft = 0; + } + + /* Figure out position of GIF file in real device Y axis: */ + if (ScreenHeight * ZoomFactor <= DeviceMaxY + 1) { + /* Device is big enough to hold all the image Y axis: */ + *ScreenTop = 0; + *DeviceTop = (DeviceMaxY - ScreenHeight * ZoomFactor) / 2; + } + else { + /* Device is too small to hold all the image Y axis: */ + switch (Why) { + case SET_POSITION_RESET: + *ScreenTop = 0; + break; + case SET_POSITION_ZOOM_U: + *ScreenTop += DeviceMaxY / (2 * ZoomFactor); + break; + case SET_POSITION_ZOOM_D: + *ScreenTop -= DeviceMaxY / (4 * ZoomFactor); + break; + case SET_POSITION_PAN: + if (MoveY != 0) *ScreenTop += MoveY; + break; + } + if (*ScreenTop < 0) *ScreenTop = 0; + if ((ScreenHeight - *ScreenTop) * ZoomFactor < DeviceMaxY + 1) + *ScreenTop = (ScreenHeight * ZoomFactor - + DeviceMaxY - 1) / ZoomFactor; + *DeviceTop = 0; + } + + /* Make sure the position is on Byte boundary (8 pixels per byte): */ + *DeviceLeft &= 0xfff8; +} + +/****************************************************************************** +* Routine to clear graphic device: * +******************************************************************************/ +static void ClearGraphDevice(void) +{ + cleardevice(); +} + +/****************************************************************************** +* Routine to open graphic device: * +******************************************************************************/ +static void OpenGraphDevice(void) +{ + int GraphDriver = HERCMONO, GraphMode = HERCMONOHI; + + if (registerbgidriver(Herc_driver) < 0) + GIF_EXIT("Cannt register graphic device."); + + initgraph(&GraphDriver, &GraphMode, ""); + if (graphresult() != grOk) + GIF_EXIT("Graphics System Error (No Hercules!?)."); +} + +/***************************************************************************** +* Routine to close and shutdown graphic mode : * +*****************************************************************************/ +static void CloseGraphDevice(void) +{ + closegraph(); /* Return the system to text mode. */ +} + +/***************************************************************************** +* Routine to evaluate dithered scanlines out of given ones, using Size * +* dithering matrix, starting from Row. The given scanlines are NOT modified. * +*****************************************************************************/ +static void EvalDitheredScanline(GifRowType *ScreenBuffer, int Row, + int RowSize, GifRowType *DitherBuffer) +{ + static char Dither2[2][2] = { /* See Foley & Van Dam pp. 597-601. */ + { 1, 3 }, + { 4, 2 } + }; + static char Dither3[3][3] = { + { 7, 9, 5 }, + { 2, 1, 4 }, + { 6, 3, 8 } + }; + static char Dither4[4][4] = { + { 1, 9, 3, 11 }, + { 13, 5, 15, 7 }, + { 4, 12, 2, 10 }, + { 16, 8, 14, 6 } + }; + int i, j, k, Level; + long Intensity; + GifColorType *ColorMapEntry; + + /* Scan the Rows (Size rows) evaluate intensity every Size pixel and use */ + /* the dither matrix to set the dithered result; */ + for (i = 0; i <= RowSize - DitherSize; i += DitherSize) { + Intensity = 0; + for (j = Row; j < Row + DitherSize; j++) + for (k = 0; k < DitherSize; k++) { + ColorMapEntry = &ColorMap[ScreenBuffer[j][i+k]]; + Intensity += 30 * ((int) ColorMapEntry->Red) + + 59 * ((int) ColorMapEntry->Green) + + 11 * ((int) ColorMapEntry->Blue); + } + + /* Find the intensity level (between 0 and Size^2) of our matrix: */ + /* Expression is "Intensity * BWThreshold / (25500 * DefThresh)" */ + /* but to prevent from overflow in the long evaluation we do this:*/ + Level = ((Intensity / 2550) * ((long) DEFAULT_THRESHOLD) / + (((long) BWThreshold) * 10)); + switch (DitherSize) { + case 2: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither2[j][k] <= Level; + break; + case 3: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither3[j][k] <= Level; + break; + case 4: + for (j = 0; j < DitherSize; j++) + for (k = 0; k < DitherSize; k++) + DitherBuffer[j][i+k] = Dither4[j][k] <= Level; + break; + } + } +} + +/****************************************************************************** +* The real drawing of the image is performed here. Few things are taken into * +* account: * +* 1. The zoom factor. If > 1 each pixel is multiplied this amount vertically * +* and horizontally. * +* 2. The Invert flag. If TRUE each pixel before drawn is inverted. * +* 3. The rendering mode and dither matrix flag if dithering is selected. * +* The image is drawn from ScreenBuffer ScreenTop/Left in the bottom/right * +* directions, onto the Device DeviceTop/Left in the bottom/right direction * +* This routine was optimized for the hercules graphic card and should be * +* handled carfully as it is device dependent. * +* Pressing space during drawing will abort this routine. * +******************************************************************************/ +static void DrawScreen(GifRowType *ScreenBuffer, GifRowType *DitherBuffer, + int DeviceTop, int DeviceLeft, int DeviceMaxX, int DeviceMaxY, + int ScreenTop, int ScreenLeft, int ScreenWidth, int ScreenHeight) +{ + unsigned int Offset; + int i, j, k, l, m, CountZoomJ, CountZoomI, + DitheredLinesLeft = 0, DitheredLinesCount, MapInvert[2]; + GifByteType DeviceByte; + GifPixelType *Line; + GifColorType *ColorMapEntry; + + ClearGraphDevice(); /* Make sure we start from scratch. */ + + if (InvertFlag) { /* Make the inversion as fast a possible. */ + MapInvert[0] = 1; + MapInvert[1] = 0; + } + else { + MapInvert[0] = 0; + MapInvert[1] = 1; + } + + for (CountZoomJ = ZoomFactor, j = ScreenTop, l = DeviceTop, DeviceByte = 0; + j < ScreenHeight && l <= DeviceMaxY; l++) { + Line = ScreenBuffer[j]; + + /* We are going to access the hercules frame buffer directly: */ + Offset = 0x2000 * (l & 0x03) + (l >> 2) * 90 + (DeviceLeft >> 3); + + /* Abort drawing if space bar was pressed: */ + if (MyKbHit() && GetKey() == ' ') return; + + /* We decide right here what method to map Colors to BW so the inner */ + /* loop will be independent of it (and therefore faster): */ + switch(ColorToBWMapping) { + case C2BW_BACK_GROUND: + for (CountZoomI = ZoomFactor, i = ScreenLeft, k = DeviceLeft, m = 0; + i < ScreenWidth && k <= DeviceMaxX;) { + /* The following lines are equivalent to the putpixel */ + /* (and making it real machine dependent...) by almost */ + /* factor of 3: */ + /* putpixel(k++, l, MapInvert[ColorToBW(Line[i])]); */ + DeviceByte = (DeviceByte << 1) + + MapInvert[Line[i] != BackGround]; + if (++m == 8) { + /* We have byte - place it on hercules frame buffer: */ + k += 8; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + m = 0; + } + + if (!--CountZoomI) { + /* Go to next column: */ + i++; + CountZoomI = ZoomFactor; + } + } + if (k < DeviceMaxX) { + /* Poke last byte also: */ + DeviceByte <<= 8 - m; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + } + break; + case C2BW_GREY_LEVELS: + for (CountZoomI = ZoomFactor, i = ScreenLeft, k = DeviceLeft, m = 0; + i < ScreenWidth && k <= DeviceMaxX;) { + /* The following lines are equivalent to the putpixel */ + /* (and making it real machine dependent...) by almost */ + /* factor of 3: */ + /* putpixel(k++, l, MapInvert[ColorToBW(Line[i])]); */ + + ColorMapEntry = &ColorMap[Line[i]]; + /* For the transformation from RGB to BW, see Folley & */ + /* Van Dam pp 613: The Y channel is the BW we need: */ + /* As colors are 255 maximum, the result can be up to */ + /* 25500 which is still in range of our 16 bits integers.*/ + DeviceByte = (DeviceByte << 1) + + MapInvert[(30 * (int) ColorMapEntry->Red) + + 59 * ((int) ColorMapEntry->Green) + + 11 * ((int) ColorMapEntry->Blue) > + BWThreshold]; + if (++m == 8) { + /* We have byte - place it on hercules frame buffer: */ + k += 8; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + m = 0; + } + + if (!--CountZoomI) { + /* Go to next column: */ + i++; + CountZoomI = ZoomFactor; + } + } + if (k < DeviceMaxX) { + /* Poke last byte also: */ + DeviceByte <<= 8 - m; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + } + break; + case C2BW_DITHER: + if (DitheredLinesLeft-- == 0) { + EvalDitheredScanline(ScreenBuffer, + (j < ScreenHeight - DitherSize ? j : + ScreenHeight - DitherSize), + ScreenWidth, DitherBuffer); + DitheredLinesLeft = DitherSize - 1; + DitheredLinesCount = 0; + } + Line = DitherBuffer[DitheredLinesCount++]; + for (CountZoomI = ZoomFactor, i = ScreenLeft, k = DeviceLeft, m = 0; + i < ScreenWidth && k <= DeviceMaxX;) { + /* The following lines are equivalent to the putpixel */ + /* (and making it real machine dependent...) by almost */ + /* factor of 3: */ + /* putpixel(k++, l, MapInvert[Line[i]]); */ + DeviceByte = (DeviceByte << 1) + MapInvert[Line[i]]; + if (++m == 8) { + /* We have byte - place it on hercules frame buffer: */ + k += 8; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + m = 0; + } + + if (!--CountZoomI) { + /* Go to next column: */ + i++; + CountZoomI = ZoomFactor; + } + } + if (k < DeviceMaxX) { + /* Poke last byte also: */ + DeviceByte <<= 8 - m; + pokeb(DEVICE_BASE, Offset++, DeviceByte); + } + break; + } + + if (!--CountZoomJ) { + /* Go to next row: */ + j++; + CountZoomJ = ZoomFactor; + } + } +} + +/****************************************************************************** +* Walks along the current image, while printing pixel value and position. * +* 4 arrows may be used, and any other key will abort this operation * +* As there is no XOR mode for text, we copy all Page 0 to Page 1 before we * +* start this, and copy it back each time... * +******************************************************************************/ +static void DoCursorMode(GifRowType *ScreenBuffer, + int ScreenLeft, int ScreenTop, int ScreenWidth, int ScreenHeight, + int DeviceLeft, int DeviceTop) +{ + int GetK, DeviceRight, DeviceBottom, x, y, CursorTextY, Step; + GifPixelType Pixel; + char s[80]; + char far *Page0, *Page1; + + Page0 = MK_FP(DEVICE_PAGE0, 0); + Page1 = MK_FP(DEVICE_PAGE1, 0); + + memcpy(Page1, Page0, 0x8000); + + + DeviceRight = DeviceLeft + (ScreenWidth - ScreenLeft) * ZoomFactor; + if (DeviceRight > HERC_MAX_X) DeviceRight = HERC_MAX_X; + + DeviceBottom = DeviceTop + (ScreenHeight - ScreenTop) * ZoomFactor; + if (DeviceBottom > HERC_MAX_Y) DeviceBottom = HERC_MAX_Y; + + x = (DeviceLeft + DeviceRight) / 2; + y = (DeviceTop + DeviceBottom) / 2; + + while (TRUE) { + Pixel = ScreenBuffer[ScreenTop + (y - DeviceTop) / ZoomFactor] + [ScreenLeft + (x - DeviceLeft) / ZoomFactor]; + sprintf(s, "Color = %d [%d, %d, %d], X = %d, Y = %d.", + Pixel, + ColorMap[Pixel].Red, + ColorMap[Pixel].Green, + ColorMap[Pixel].Blue, + (x - DeviceLeft) / ZoomFactor, + (y - DeviceTop) / ZoomFactor); + CursorTextY = (y > HERC_MAX_Y / 2 ? HERC_MAX_Y / 4 : + 3 * HERC_MAX_Y / 4); + setviewport(CURSOR_TEXT_X, CursorTextY, + CURSOR_TEXT_X + textwidth(s), CursorTextY + textheight(s), + TRUE); + clearviewport(); + setviewport(0, 0, HERC_MAX_X, HERC_MAX_Y, TRUE); + setcolor(1); /* We only have one color here. */ + line(0, y, HERC_MAX_X, y); + line(x, 0, x, HERC_MAX_Y); + outtextxy(CURSOR_TEXT_X, CursorTextY, s); + GetK = GetKey(); + + memcpy(Page0, Page1, 0x8000); + + Step = 10; + switch (GetK) { + case '1': + GetK = KEY_END; + break; + case '2': + GetK = KEY_DOWN; + break; + case '3': + GetK = KEY_PGDN; + break; + case '4': + GetK = KEY_LEFT; + break; + case '6': + GetK = KEY_RIGHT; + break; + case '7': + GetK = KEY_HOME; + break; + case '8': + GetK = KEY_UP; + break; + case '9': + GetK = KEY_PGUP; + break; + default: + Step = 1; + } + + switch (GetK) { + case KEY_LEFT: + x -= Step; + break; + case KEY_RIGHT: + x += Step; + break; + case KEY_UP: + y -= Step; + break; + case KEY_DOWN: + y += Step; + break; + case KEY_PGUP: + y -= Step; + x += Step; + break; + case KEY_PGDN: + y += Step; + x += Step; + break; + case KEY_HOME: + y -= Step; + x -= Step; + break; + case KEY_END: + y += Step; + x -= Step; + break; + default: + return; + } + if (x < DeviceLeft) x = DeviceLeft; + if (x >= DeviceRight) x = DeviceRight; + if (y < DeviceTop) y = DeviceTop; + if (y >= DeviceBottom) y = DeviceBottom; + } +} + +/****************************************************************************** +* Return non zero value if at list one character exists in keyboard queue. * +* This routine emulates kbhit() which do uses stdin and useless for us. * +******************************************************************************/ +static int MyKbHit(void) +{ + return bioskey(1); +} + +/****************************************************************************** +* Get a key from keyboard directly (bypass stdin as we might redirect it). * +* This routine emulates getch() which do uses stdin and useless for us. * +******************************************************************************/ +static int MyGetCh(void) +{ + static int Extended = 0; + int c; + + if (Extended) { + c = Extended; + Extended = 0; + return c; + } + else { + c = bioskey(0); + if (c & 0x0ff) + return c; + else { + Extended = c >> 8; + return 0; + } + } +} + +/****************************************************************************** +* Get a key from keyboard, and translating operational keys into special * +* codes (>255). Lower case characters are upercased. * +******************************************************************************/ +static int GetKey(void) +{ + char c; + + while (TRUE) switch (c = MyGetCh()) { + case 0: /* Extended code - get the next extended char. */ + switch (MyGetCh()) { + case 75: return KEY_LEFT; + case 77: return KEY_RIGHT; + case 72: return KEY_UP; + case 80: return KEY_DOWN; + case 71: return KEY_HOME; + case 79: return KEY_END; + case 73: return KEY_PGUP; + case 81: return KEY_PGDN; + case 83: return KEY_DELETE; + case 82: return KEY_INSERT; + } + break; + case 8: + return KEY_BSPACE; + case 10: + case 13: + return KEY_RETURN; + case 27: + return KEY_ESC; + default: + if (isprint(c)) { + if (islower(c)) + return toupper(c); + else + return c; + } + else { + Tone(800, 100); + Tone(300, 200); + } + } + + return 0; /* Should never be here any case. */ +} + +/****************************************************************************** +* Routine to make some sound with given Frequency, Time milliseconds: * +******************************************************************************/ +static void Tone(int Frequency, int Time) +{ + if (BeepsDisabled) return; + + sound(Frequency); + delay(Time); + nosound(); +} diff --git a/G/UTIL/GIF2IRIS.C b/G/UTIL/GIF2IRIS.C new file mode 100644 index 0000000..536e170 --- /dev/null +++ b/G/UTIL/GIF2IRIS.C @@ -0,0 +1,283 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber UNIX Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to display GIF file under X11 window system. * +* Options: * +* -q : quite printing mode. * +* -f : force the process to be in foreground. * +* -p PosX PosY : defines the position where to put the image. * +* -h : on line help. * +****************************************************************************** +* History: * +* 13 mar 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include "gl.h" +#include "device.h" + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2Iris" + +#define ABS(x) ((x) > 0 ? (x) : (-(x))) + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2Iris q%- f%- p%-PosX|PosY!d!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- f%- p%-PosX|PosY!d!d h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + PosFlag = FALSE, + HelpFlag = FALSE, + ForeGroundFlag = FALSE, + ColorMapSize = 0, + BackGround = 0, + IrisPosX = 0, + IrisPosY = 0, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static GifColorType + *ColorMap; + +static void Screen2Iris(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, ImageNum = 0, Size, Row, Col, Width, Height, + ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &ForeGroundFlag, + &PosFlag, &IrisPosX, &IrisPosY, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel); + GifQprintf("\n"); + Screen2Iris(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/****************************************************************************** +* The real display routine. * +******************************************************************************/ +static void Screen2Iris(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + short Val; + int i, j; + unsigned long *IrisScreenBuffer, *PBuffer; + + if (ScreenWidth > XMAXSCREEN + 1 || + ScreenHeight > YMAXSCREEN + 1) + GIF_EXIT("Input image is too big."); + + if (PosFlag) + prefposition(IrisPosX, IrisPosX + ScreenWidth - 1, + IrisPosY, IrisPosY + ScreenHeight - 1); + else + prefsize(ScreenWidth, ScreenHeight); + if (ForeGroundFlag) + foreground(); + + winopen(PROGRAM_NAME); + RGBmode(); + gconfig(); + if ((IrisScreenBuffer = (unsigned long *) + malloc(ScreenWidth * ScreenHeight * sizeof(unsigned long))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + PBuffer = IrisScreenBuffer; + for (i = ScreenHeight - 1; i >= 0; i--) + for (j = 0; j < ScreenWidth; j++) + *PBuffer++ = ColorMap[ScreenBuffer[i][j]].Red + + (ColorMap[ScreenBuffer[i][j]].Green << 8) + + (ColorMap[ScreenBuffer[i][j]].Blue << 16); + + reshapeviewport(); + lrectwrite(0, 0, ScreenWidth - 1, ScreenHeight - 1, IrisScreenBuffer); + + while (TRUE) { + if (qread(&Val) == REDRAW) { + reshapeviewport(); + lrectwrite(0, 0, ScreenWidth - 1, ScreenHeight - 1, + IrisScreenBuffer); + } + } +} diff --git a/G/UTIL/GIF2PS.C b/G/UTIL/GIF2PS.C new file mode 100644 index 0000000..4cad1cd --- /dev/null +++ b/G/UTIL/GIF2PS.C @@ -0,0 +1,387 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to dump GIF file into PostScript type printers * +* Options: * +* -q : quite printing mode. * +* -x : force image to be horizontal. * +* -y : force image to be vertical. * +* -s x y : force image to be of given size. * +* -p x y : force image to be positioned at given position in page. * +* -i : invert the image. * +* -n n : number of copies. * +* -h : on line help. * +****************************************************************************** +* History: * +* 22 Dec 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2PS" + +#define PAGE_WIDTH 7.5 /* All dimensions are in inches. */ +#define PAGE_HEIGHT 9.0 +#define FULL_PAGE_WIDTH 8.5 +#define FULL_PAGE_HEIGHT 11.0 + +#define UNKNOWN_ORIENT 0 +#define HORIZONTAL_ORIENT 1 +#define VERTICAL_ORIENT 2 + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2PS q%- x%- y%- s%-SizeX|SizeY!F!F p%-PosX|PosY!F!F i%- n%-#Copies!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- x%- y%- s%-SizeX|SizeY!F!F p%-PosX|PosY!F!F i%- n%-#Copies!d h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + ForceXFlag = FALSE, + ForceYFlag = FALSE, + SizeFlag = FALSE, + PosFlag = FALSE, + InvertFlag = FALSE, + NumCopiesFlag = FALSE, + HelpFlag = FALSE, + NumOfCopies = 1, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }, /* be read - offsets and jumps... */ + PSOrientation; +static double PSSizeX, PSSizeY, PSPosX, PSPosY; +static GifColorType + *ColorMap; + +static void DumpScreen2PS(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); +static void PutString(unsigned char *Line, int Len); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr,&GifQuitePrint, + &ForceXFlag, &ForceYFlag, &SizeFlag, &PSSizeX, &PSSizeY, + &PosFlag, &PSPosX, &PSPosY, + &InvertFlag, &NumCopiesFlag, &NumOfCopies, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (ForceXFlag) + PSOrientation = HORIZONTAL_ORIENT; + else if (ForceYFlag) + PSOrientation = VERTICAL_ORIENT; + else + PSOrientation = UNKNOWN_ORIENT; + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + DumpScreen2PS(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/****************************************************************************** +* The real dumping routine. * +******************************************************************************/ +static void DumpScreen2PS(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + int i, j; + double Aspect; + GifByteType *OutLine, Data; + GifPixelType *Line; + GifColorType *ColorMapEntry; + + /* If user did not enforce orientation, pick the best one. */ + if (PSOrientation == UNKNOWN_ORIENT) + if (ScreenWidth > ScreenHeight) + PSOrientation = VERTICAL_ORIENT; + else + PSOrientation = HORIZONTAL_ORIENT; + + Aspect = ((double) ScreenHeight) / ((double) ScreenWidth); + + if (!SizeFlag) + switch (PSOrientation) { + case HORIZONTAL_ORIENT: + if (Aspect > PAGE_HEIGHT / PAGE_WIDTH) { + PSSizeX = PAGE_HEIGHT / Aspect; + PSSizeY = PAGE_HEIGHT; + } + else { + PSSizeX = PAGE_WIDTH; + PSSizeY = PAGE_WIDTH * Aspect; + } + break; + case VERTICAL_ORIENT: + if (1 / Aspect > PAGE_HEIGHT / PAGE_WIDTH) { + PSSizeX = PAGE_HEIGHT * Aspect; + PSSizeY = PAGE_HEIGHT; + } + else { + PSSizeX = PAGE_WIDTH; + PSSizeY = PAGE_WIDTH / Aspect; + } + break; + } + else { + if (PAGE_WIDTH < PSSizeX) { + GIF_MESSAGE("X Size specified is too big, page size selected."); + PSSizeX = PAGE_WIDTH; + } + if (PAGE_HEIGHT < PSSizeY) { + GIF_MESSAGE("Y Size specified is too big, page size selected."); + PSSizeX = PAGE_HEIGHT; + } + } + + if (!PosFlag) { + PSPosX = (FULL_PAGE_WIDTH - PSSizeX) / 2; + PSPosY = (FULL_PAGE_HEIGHT - PSSizeY) / 2; + } + else { + if (PSPosX + PSSizeX > PAGE_WIDTH || PSPosY + PSSizeY > PAGE_HEIGHT) + GIF_EXIT("Requested position will put image out of page, aborted."); + } + + /* Time to dump out the PostScript header: */ + printf("%%!\n"); + printf("%%%%Creator: %s\n", PROGRAM_NAME); + printf("/#copies %d def\n", NumOfCopies); + printf("gsave\n"); + printf("72 72 scale\t\t\t\t%% Lets talk inches.\n"); + printf("/oneline %d string def\t\t\t%% Allocate one scan line.\n", + ScreenWidth); + printf("/drawimage {\n"); + printf("\t%d %d 8 [%d 0 0 %d 0 %d]\n", ScreenWidth, ScreenHeight, + ScreenWidth, -ScreenHeight, ScreenHeight); + printf("\t{ currentfile oneline readhexstring pop } image\n"); + printf("} def\n"); + switch (PSOrientation) { + case HORIZONTAL_ORIENT: + printf("%lf %lf translate\n", PSPosX, PSPosY); + printf("%lf %lf scale\n", PSSizeX, PSSizeY); + break; + case VERTICAL_ORIENT: + printf("%lf %lf translate\n", PSPosX + PSSizeX, PSPosY); + printf("90 rotate\n"); + printf("%lf %lf scale\n", PSSizeY, PSSizeX); + break; + } + printf("drawimage\n"); + + if ((OutLine = (GifByteType *) malloc(sizeof(GifByteType) * ScreenWidth)) + == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < ScreenHeight; i++) { + GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); + + Line = ScreenBuffer[i]; + for (j = 0; j < ScreenWidth; j++) { + ColorMapEntry = &ColorMap[Line[j]]; + Data = (30 * ((unsigned int) ColorMapEntry->Red) + + 59 * ((unsigned int) ColorMapEntry->Green) + + 11 * ((unsigned int) ColorMapEntry->Blue)) / 100; + OutLine[j] = InvertFlag ? 255 - Data : Data; + } + + PutString(OutLine, ScreenWidth); + } + free(OutLine); + + printf("\nshowpage\n"); + printf("grestore\n"); +} + +/****************************************************************************** +* Dumps the string of given length as 2 hexdigits per byte 39 bytes per line. * +******************************************************************************/ +static void PutString(unsigned char *Line, int Len) +{ + int i; + static Counter = 0; + static char *Hex = "0123456789ABCDEF"; + + for (i = 0; i < Len; i++) { + if (++Counter % 40 == 0) { + putchar('\n'); + Counter = 1; + } + putchar(Hex[Line[i] >> 4]); + putchar(Hex[Line[i] & 0x0f]); + } +} diff --git a/G/UTIL/GIF2RGB.C b/G/UTIL/GIF2RGB.C new file mode 100644 index 0000000..6ad2d6f --- /dev/null +++ b/G/UTIL/GIF2RGB.C @@ -0,0 +1,337 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to convert GIF file to RGB 24 bits. * +* Options: * +* -q : quite printing mode. * +* -1 : dump as one file using RGBRGB triples. * +* -h : on line help. * +* -o FileName : specify the output file name(s). * +****************************************************************************** +* History: * +* 5 Jan 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2RGB" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2RGB q%- 1%- o%-OutFileName!s h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- 1%- o%-OutFileName!s h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + OneFileFlag = FALSE, + HelpFlag = FALSE, + ColorMapSize = 0, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static GifColorType + *ColorMap; + +static void DumpScreen2RGB(char *FileName, int OneFileFlag, + GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count, + OutFileFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension; + char *OutFileName, + **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &OneFileFlag, &OutFileFlag, &OutFileName, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (!OutFileFlag) OutFileName = NULL; + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + /* Lets dump it - set the global variables required and do it: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel); + DumpScreen2RGB(OutFileName, OneFileFlag, + ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/****************************************************************************** +* The real dumping routine. * +******************************************************************************/ +static void DumpScreen2RGB(char *FileName, int OneFileFlag, + GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + int i, j; + GifRowType GifRow; + static GifColorType + *ColorMapEntry; + FILE *f[3]; + + if (FileName != NULL) { + char OneFileName[80]; + + if (OneFileFlag) { +#ifdef __MSDOS__ + if ((f[0] = fopen(FileName, "wb")) == NULL) +#else + if ((f[0] = fopen(FileName, "w")) == NULL) +#endif /* __MSDOS__ */ + GIF_EXIT("Can't open input file name."); + } + else { + static char *Postfixes[] = { ".R", ".G", ".B" }; + + for (i = 0; i < 3; i++) { + strcpy(OneFileName, FileName); + strcat(OneFileName, Postfixes[i]); + +#ifdef __MSDOS__ + if ((f[i] = fopen(OneFileName, "wb")) == NULL) +#else + if ((f[i] = fopen(OneFileName, "w")) == NULL) +#endif /* __MSDOS__ */ + + GIF_EXIT("Can't open input file name."); + } + } + } + else { + OneFileFlag = TRUE; + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + + f[0] = stdout; + } + + if (OneFileFlag) { + unsigned char *Buffer, *BufferP; + + if ((Buffer = (unsigned char *) malloc(ScreenWidth * 3)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < ScreenHeight; i++) { + GifRow = ScreenBuffer[i]; + GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); + for (j = 0, BufferP = Buffer; j < ScreenWidth; j++) { + ColorMapEntry = &ColorMap[GifRow[j]]; + *BufferP++ = ColorMapEntry -> Red; + *BufferP++ = ColorMapEntry -> Green; + *BufferP++ = ColorMapEntry -> Blue; + } + if (fwrite(Buffer, ScreenWidth * 3, 1, f[0]) != 1) + GIF_EXIT("Write to file(s) failed."); + } + + free((char *) Buffer); + fclose(f[0]); + } + else { + unsigned char *Buffers[3]; + + if ((Buffers[0] = (unsigned char *) malloc(ScreenWidth)) == NULL || + (Buffers[1] = (unsigned char *) malloc(ScreenWidth)) == NULL || + (Buffers[2] = (unsigned char *) malloc(ScreenWidth)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < ScreenHeight; i++) { + GifRow = ScreenBuffer[i]; + GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); + for (j = 0; j < ScreenWidth; j++) { + ColorMapEntry = &ColorMap[GifRow[j]]; + Buffers[0][j] = ColorMapEntry -> Red; + Buffers[1][j] = ColorMapEntry -> Green; + Buffers[2][j] = ColorMapEntry -> Blue; + } + if (fwrite(Buffers[0], ScreenWidth, 1, f[0]) != 1 || + fwrite(Buffers[1], ScreenWidth, 1, f[1]) != 1 || + fwrite(Buffers[2], ScreenWidth, 1, f[2]) != 1) + GIF_EXIT("Write to file(s) failed."); + } + + free((char *) Buffers[0]); + free((char *) Buffers[1]); + free((char *) Buffers[2]); + fclose(f[0]); + fclose(f[1]); + fclose(f[2]); + } +} diff --git a/G/UTIL/GIF2RLE.C b/G/UTIL/GIF2RLE.C new file mode 100644 index 0000000..3669dcc --- /dev/null +++ b/G/UTIL/GIF2RLE.C @@ -0,0 +1,276 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to convert GIF file RLE format (utah raster toolkit). * +* Options: * +* -q : quite printing mode. * +* -a : add alpha channel with full coverage. * +* -h : on line help. * +****************************************************************************** +* History: * +* 5 Jan 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#include "rle.h" /* The rle tool kit header files. */ + +#define PROGRAM_NAME "Gif2Rle" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2Rle q%- a%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- a%- h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + BackGround = 0, + AlphaFlag = FALSE, + HelpFlag = FALSE, + ColorMapSize = 0, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static GifColorType + *ColorMap; + +static void DumpScreen2Rle(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &AlphaFlag, &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + 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: */ + BackGround = GifFile -> SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel); + DumpScreen2Rle(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } +} + +/****************************************************************************** +* The real dumping routine. * +******************************************************************************/ +static void DumpScreen2Rle(GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + int i, j; + char Comment[80]; + rle_pixel *rows[4]; + GifRowType GifRow; + static GifColorType + *ColorMapEntry; + + if (AlphaFlag) RLE_SET_BIT(rle_dflt_hdr, RLE_ALPHA); + rle_dflt_hdr.alpha = AlphaFlag != 0; + rle_dflt_hdr.rle_file = stdout; + rle_dflt_hdr.xmin = 0; + rle_dflt_hdr.ymin = 0; + rle_dflt_hdr.xmax = ScreenWidth - 1; + rle_dflt_hdr.ymax = ScreenHeight - 1; + sprintf(Comment, "origin=GIF format, %d colors.", ColorMapSize); + rle_putcom(Comment, &rle_dflt_hdr); + rle_put_setup(&rle_dflt_hdr); + + for (i = 0; i < 4; i++) + if ((rows[i] = (rle_pixel *) malloc(sizeof(rle_pixel) * ScreenWidth)) + == NULL) + GIF_EXIT("Failed to allocated memory required, aborted."); + + if (AlphaFlag) { + /* Initial the alpha channel to full coverage: */ + for (i = 0; i < ScreenWidth; i++) rows[0][i] = 255; + } + + for (i = 0; i < ScreenHeight; i++) { + /* Flip the image vertically as rle files start at the bollom... */ + GifRow = ScreenBuffer[ScreenHeight - i - 1]; + GifQprintf("\b\b\b\b%-4d", ScreenHeight - i); + for (j = 0; j < ScreenWidth; j++) { + ColorMapEntry = &ColorMap[GifRow[j]]; + rows[1][j] = ColorMapEntry -> Red; + rows[2][j] = ColorMapEntry -> Green; + rows[3][j] = ColorMapEntry -> Blue; + } + rle_putrow( &rows[1], ScreenWidth, &rle_dflt_hdr ); + } + + rle_puteof( &rle_dflt_hdr ); +} diff --git a/G/UTIL/GIF2X11.C b/G/UTIL/GIF2X11.C new file mode 100644 index 0000000..23bb00f --- /dev/null +++ b/G/UTIL/GIF2X11.C @@ -0,0 +1,517 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to display GIF file under X11 window system. * +* Options: * +* -q : quite printing mode. * +* -p PosX PosY : defines the position where to put the image. * +* -d Display : what display should go to. * +* -f : force attempt to allocate the exact colors. This usually look bad... * +* -h : on line help. * +****************************************************************************** +* History: * +* 28 Dec 89 - Version 1.0 by Gershon Elber, color allocation is based on the * +* xgif program by John Bradley, bradley@cis.ipenn.edu. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Gif2X11" + +#define ICON_SIZE 60 +#define ABS(x) ((x) > 0 ? (x) : (-(x))) + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Gif2X11 q%- p%-PosX|PosY!d!d d%-Display!s f%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- p%-PosX|PosY!d!d d%-Display!s f%- h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + PosFlag = FALSE, + HelpFlag = FALSE, + DisplayFlag = FALSE, + ForceFlag = FALSE, + ColorMapSize = 0, + BackGround = 0, + XPosX = 0, + XPosY = 0, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ +static char + *DisplayName = NULL; +static GifColorType + *ColorMap; + +/* X specific staff goes here. XColorTable will hold the GIF image colors, */ +/* while XPixelTable will hold the pixel number so we can redirect through */ +/* it when forming the image bitmap in X format. */ +/* Note the table has 256 entry which is the maximum allowed in GIF format. */ +static XColor XColorTable[256]; +static unsigned long XPixelTable[256]; +static Display *XDisplay; +static int XScreen; +static Window Xroot, XImageWndw; +static Colormap XColorMap; +static GC XGraphContext; +static Visual *XVisual; +static XImage *XImageBuffer; +static Pixmap XIcon; +static Cursor XCursor; + +static void Screen2X(int argc, char **argv, GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight); +static void AllocateColors1(void); +static void AllocateColors2(void); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, ImageNum = 0, Size, Row, Col, Width, Height, + ExtCode, Count; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ScreenBuffer; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &PosFlag, &XPosX, &XPosY, + &DisplayFlag, &DisplayName, &ForceFlag, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Lets see if we can get access to the X server before we even start: */ + if ((XDisplay = (Display *) XOpenDisplay(DisplayName)) == NULL) + GIF_EXIT("Failed to access X server, abored."); + XScreen = DefaultScreen(XDisplay); + Xroot = RootWindow(XDisplay, XScreen); + XColorMap = DefaultColormap(XDisplay, XScreen); + XGraphContext = DefaultGC(XDisplay, XScreen); + XVisual = DefaultVisual(XDisplay, XScreen); + XSetBackground(XDisplay, XGraphContext, BlackPixel(XDisplay, XScreen)); + XSetForeground(XDisplay, XGraphContext, WhitePixel(XDisplay, XScreen)); + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j SBackGroundColor; + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel); + Screen2X(argc, argv, ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + GifQprintf("\n"); +} + +/****************************************************************************** +* The real display routine. * +******************************************************************************/ +static void Screen2X(int argc, char **argv, GifRowType *ScreenBuffer, + int ScreenWidth, int ScreenHeight) +{ + int i, j, c, Size, x, y, + MinIntensity, MaxIntensity, AvgIntensity, IconSizeX, IconSizeY; + char *XImageData, *XIconData, KeyBuffer[81]; + double Aspect; + GifByteType *OutLine, Data; + unsigned long ValueMask; + GifPixelType *Line; + GifRowType *DitherBuffer; + GifColorType *ColorMapEntry = ColorMap; + XSetWindowAttributes SetWinAttr; + XSizeHints Hints; + XEvent Event; + XExposeEvent *EEvent; + XComposeStatus Stat; + KeySym KS; + + /* Let find out what are the intensities in the color map: */ + MaxIntensity = 0; + MinIntensity = 256 * 100; + for (i = 0; i < ColorMapSize; i++) { + c = ColorMapEntry[i].Red * 30 + + ColorMapEntry[i].Green * 59 + + ColorMapEntry[i].Blue * 11; + if (c > MaxIntensity) MaxIntensity = c; + if (c < MinIntensity) MinIntensity = c; + } + AvgIntensity = (MinIntensity + MaxIntensity) / 2; + + /* The big trick here is to select the colors so lets do this first: */ + if (ForceFlag) + AllocateColors2(); + else + AllocateColors1(); + + SetWinAttr.background_pixel = BlackPixel( XDisplay, XScreen ); + SetWinAttr.border_pixel = WhitePixel( XDisplay, XScreen ); + ValueMask = CWBackPixel | CWBorderPixel; + + Hints.flags = PSize | PMinSize | PMaxSize; + Hints.x = Hints.y = 1; + Hints.width = Hints.min_width = Hints.max_width = ScreenWidth; + Hints.height = Hints.min_height = Hints.max_height = ScreenHeight; + if (PosFlag) { + Hints.flags |= USPosition; + Hints.x = XPosX; + Hints.y = XPosY; + } + + XImageWndw = XCreateWindow(XDisplay, Xroot, XPosX, XPosY, + ScreenWidth, ScreenHeight, + 1, 0, + CopyFromParent, CopyFromParent, + ValueMask, &SetWinAttr); + + /* Set up the icon bit map to be a shrinked BW version of the image: */ + if (ScreenWidth > ScreenHeight) { + IconSizeX = (ICON_SIZE / 8) * 8; + IconSizeY = (ScreenHeight * ICON_SIZE) / ScreenWidth; + } + else { + IconSizeY = ICON_SIZE; + IconSizeX = (((ScreenWidth * ICON_SIZE) / ScreenHeight) / 8) * 8; + } + XIconData = (char *) malloc(IconSizeX * IconSizeY / 8); + memset(XIconData, 0, IconSizeX * IconSizeY / 8); + for (i = 0; i < IconSizeY; i++) { + y = (i * ScreenHeight / IconSizeY); + Size = i * IconSizeX / 8; + for (j = 0; j < IconSizeX; j++) { + x = j * ScreenWidth / IconSizeX; + c = ScreenBuffer[y][x]; + c = ColorMapEntry[c].Red * 30 + + ColorMapEntry[c].Green * 59 + + ColorMapEntry[c].Blue * 11 > AvgIntensity; + XIconData[Size + j / 8] |= c << (j % 8); + } + } + + XIcon = XCreateBitmapFromData(XDisplay, XImageWndw, XIconData, + IconSizeX, IconSizeY); + + XSetStandardProperties(XDisplay, XImageWndw, + PROGRAM_NAME, PROGRAM_NAME, XIcon, + argv, argc, + &Hints); + + XSelectInput(XDisplay, XImageWndw, ExposureMask | KeyPressMask); + + /* Set out own cursor: */ + XCursor = XCreateFontCursor(XDisplay, XC_diamond_cross); + XDefineCursor(XDisplay, XImageWndw, XCursor); + + XMapWindow(XDisplay, XImageWndw); + + /* Create the image in X format: */ + if ((XImageData = (char *) malloc(ScreenWidth * ScreenHeight)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < ScreenHeight; i++) { + y = i * ScreenWidth; + for (j = 0; j < ScreenWidth; j++) + XImageData[y + j] = XPixelTable[ScreenBuffer[i][j]]; + } + XImageBuffer = XCreateImage(XDisplay, XVisual, 8, ZPixmap, 0, + XImageData, ScreenWidth, ScreenHeight, + 8, ScreenWidth); + + while (TRUE) { + XNextEvent(XDisplay, &Event); + switch (Event.type) { + case Expose: + EEvent = (XExposeEvent *) &Event; + XPutImage(XDisplay, XImageWndw, XGraphContext, XImageBuffer, + EEvent -> x, EEvent -> y, + EEvent -> x, EEvent -> y, + EEvent -> width, EEvent -> height); + break; + case KeyPress: + XLookupString(&Event, KeyBuffer, 80, &KS, &Stat); + if (KeyBuffer[0] == 3) return; + break; + } + } +} + +/****************************************************************************** +* Routine to allocate the requested colors from the X server. * +* Colors are allocated until success by stripping off the least bits of the * +* colors. * +******************************************************************************/ +static void AllocateColors1(void) +{ + int Strip, Msk, i, j; + char Msg[80]; + + for (i = 0; i < 256; i++) + XPixelTable[i] = 0; /* Put reasonable color for out of range. */ + + for (Strip = 0, Msk = 0xff; Strip < 8; Strip++, Msk <<= 1) { + for (i = 0; i < ColorMapSize; i++) { + /* Prepere color entry in X format. */ + XColorTable[i].red = (ColorMap[i].Red & Msk) << 8; + XColorTable[i].green = (ColorMap[i].Green & Msk) << 8; + XColorTable[i].blue = (ColorMap[i].Blue & Msk) << 8; + XColorTable[i].flags = DoRed | DoGreen | DoBlue; + if (XAllocColor(XDisplay, XColorMap, &XColorTable[i])) + XPixelTable[i] = XColorTable[i].pixel; + else + break; + } + if (i < ColorMapSize) + XFreeColors(XDisplay, XColorMap, XPixelTable, i, 0L); + else + break; + } + + if (Strip == 8) + GIF_EXIT("Can not display the image - not enough colors available."); + + if (Strip != 0) { + sprintf(Msg, "%d bits were stripped off the color map.", Strip); + GIF_MESSAGE(Msg); + } +} + +/****************************************************************************** +* Routine to allocate the requested colors from the X server. * +* Two stages are performed: * +* 1. Colors are requested directly. * +* 2. If not enough colors can be allocated, the closest current color * +* in current table is selected instead. * +* This allocation is not optimal as when fail to allocate all colors one * +* should pick the right colors to do allocate in order to minimize the * +* closest distance from the unallocated ones under some norm (what is a good * +* norm for the RGB space?). Improve it if you are bored. * +******************************************************************************/ +static void AllocateColors2(void) +{ + int i, j, Index = 0, Count = 0, XNumOfColors; + char Msg[80]; + unsigned long D, Distance, AvgDistance = 0, Red, Green, Blue; + GifBooleanType Failed = FALSE; + XColor *XOldColorTable; + + for (i = 0; i < 256; i++) { + if (i < ColorMapSize) { /* Prepere color entry in X format. */ + XColorTable[i].red = ColorMap[i].Red << 8; + XColorTable[i].green = ColorMap[i].Green << 8; + XColorTable[i].blue = ColorMap[i].Blue << 8; + XColorTable[i].flags = DoRed | DoGreen | DoBlue; + XPixelTable[i] = -1; /* Not allocated yet. */ + } + else + XPixelTable[i] = 0; /* Put reasonable color for out of range. */ + } + + for (i = 0; i < ColorMapSize; i++) /* Allocate the colors from X: */ + if (XAllocColor(XDisplay, XColorMap, &XColorTable[i])) + XPixelTable[i] = XColorTable[i].pixel; + else + Failed = TRUE; + + if (Failed) { + XNumOfColors = DisplayCells(XDisplay, XScreen); + XOldColorTable = (XColor *) malloc(sizeof(XColor) * XNumOfColors); + for (i = 0; i < XNumOfColors; i++) XOldColorTable[i].pixel = i; + XQueryColors(XDisplay, XColorMap, XOldColorTable, XNumOfColors); + + for (i = 0; i < ColorMapSize; i++) { + /* Allocate closest colors from X: */ + if (XPixelTable[i] == -1) { /* Failed to allocate this one. */ + Distance = 0xffffffff; + + Red = XColorTable[i].red; + Green = XColorTable[i].green; + Blue = XColorTable[i].blue; + + for (j = 0; j < XNumOfColors; j++) { + /* Find the closest color in 3D RGB space using L1 norm. */ + if ((D = ABS(Red - XOldColorTable[j].red) + + ABS(Green - XOldColorTable[j].green) + + ABS(Blue - XOldColorTable[j].blue)) < Distance) { + Distance = D; + Index = j; + } + } + XPixelTable[i] = Index; + + AvgDistance += Distance; + Count++; + } + } + free(XOldColorTable); + + sprintf(Msg, "Colors will be approximated (average error = %d).\n", + AvgDistance / Count); + GIF_MESSAGE(Msg); + } +} diff --git a/G/UTIL/GIFASM.C b/G/UTIL/GIFASM.C new file mode 100644 index 0000000..5c4e7a7 --- /dev/null +++ b/G/UTIL/GIFASM.C @@ -0,0 +1,314 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to assemble/disassemble GIF files: disassembles multi image file * +* into seperated files, or assembles few single image GIF files into one. * +* Options: * +* -q : quite printing mode. * +* -a : assemble few files into one (default) * +* -d name : disassmble given GIF file into seperate files derived from name. * +* -h : on line help. * +****************************************************************************** +* History: * +* 7 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifAsm" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifAsm q%- a%- d%-OutFileName!s h%- GifFile(s)!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- a%- d%-OutFileName!s h%- GifFile(s)!*s"; +#endif /* SYSV */ + +static int + AsmFlag = FALSE; + +static void DoAssembly(int NumFiles, char **FileNames); +static void DoDisassembly(char *InFileName, char *OutFileName); +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, DisasmFlag = FALSE, HelpFlag = FALSE; + char **FileNames = NULL, *OutFileName; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &AsmFlag, &DisasmFlag, &OutFileName, + &HelpFlag, &NumFiles, &FileNames)) != FALSE) { + GAPrintErrMsg(Error); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (!AsmFlag && !DisasmFlag) AsmFlag = TRUE; /* Make default - assemble. */ + if (AsmFlag && NumFiles < 2) { + GIF_MESSAGE("At list two GIF files are required to assembly operation."); + GAPrintHowTo(CtrlStr); + exit(1); + } + if (!AsmFlag && NumFiles > 1) { + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (AsmFlag) + DoAssembly(NumFiles, FileNames); + else + DoDisassembly(NumFiles == 1 ? *FileNames : NULL, OutFileName); +} + +/****************************************************************************** +* Perform the assembly operation - take few input files into one output. * +******************************************************************************/ +static void DoAssembly(int NumFiles, char **FileNames) +{ + int i, ExtCode, CodeSize; + GifRecordType RecordType; + GifByteType *Extension, *CodeBlock; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + for (i = 0; i < NumFiles; i++) { + if ((GifFileIn = DGifOpenFileName(FileNames[i])) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* And dump out screen descriptor iff its first image. */ + if (i == 0) + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Now read image itself in decoded form as we dont */ + /* dont care what is there, and this is much faster. */ + if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR + || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || + EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, discard.*/ + while (Extension != NULL) + if (DGifGetExtensionNext(GifFileIn, &Extension) + == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); +} + +/****************************************************************************** +* Perform the disassembly operation - take one input files into few output. * +******************************************************************************/ +static void DoDisassembly(char *InFileName, char *OutFileName) +{ + int i, ExtCode, CodeSize, FileNum = 0, FileEmpty; + GifRecordType RecordType; + char CrntFileName[80], *p; + GifByteType *Extension, *CodeBlock; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + /* If name has type postfix, strip it out, and make sure name is less */ + /* or equal to 6 chars, so we will have 2 chars in name for numbers. */ + for (i = 0; i < strlen(OutFileName); i++)/* Make sure all is upper case.*/ + if (islower(OutFileName[i])) + OutFileName[i] = toupper(OutFileName[i]); + + if ((p = strrchr(OutFileName, '.')) != NULL && strlen(p) <= 4) p[0] = 0; + if ((p = strrchr(OutFileName, '/')) != NULL || + (p = strrchr(OutFileName, '\\')) != NULL || + (p = strrchr(OutFileName, ':')) != NULL) { + if (strlen(p) > 7) p[7] = 0; /* p includes the '/', '\\', ':' char. */ + } + else { + /* Only name is given for current directory: */ + if (strlen(OutFileName) > 6) OutFileName[6] = 0; + } + + /* Open input file: */ + if (InFileName != NULL) { + if ((GifFileIn = DGifOpenFileName(InFileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Scan the content of GIF file and dump image(s) to seperate file(s): */ + do { + sprintf(CrntFileName, "%s%02d.gif", OutFileName, FileNum++); + if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + FileEmpty = TRUE; + + /* And dump out its exactly same screen information: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + FileEmpty = FALSE; + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + /* Put same image descriptor to out file: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Now read image itself in decoded form as we dont */ + /* really care what is there, and this is much faster. */ + if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR + || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || + EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + break; + case EXTENSION_RECORD_TYPE: + FileEmpty = FALSE; + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, discard.*/ + while (Extension != NULL) + if (DGifGetExtensionNext(GifFileIn, &Extension) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != IMAGE_DESC_RECORD_TYPE && + RecordType != TERMINATE_RECORD_TYPE); + + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (FileEmpty) { + /* Might happen on last file - delete it if so: */ + unlink(CrntFileName); + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + if (DGifCloseFile(GifFileIn) == GIF_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); +} diff --git a/G/UTIL/GIFBG.C b/G/UTIL/GIFBG.C new file mode 100644 index 0000000..d170e72 --- /dev/null +++ b/G/UTIL/GIFBG.C @@ -0,0 +1,362 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to generate back ground image that can be used to replace constant * +* background. * +* Options: * +* -q : quite printing mode. * +* -d direction : set direction image should increase intensity. * +* -l levels : number of color levels. * +* -c r g b : colors of the back ground. * +* -m min : minimin intensity in percent. * +* -M max : maximum intensity in percent. * +* -s width height : size of image to create. * +* -h : on line help. * +****************************************************************************** +* History: * +* 9 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifBG" + +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 350 + +#define DEFAULT_COLOR_RED 0 +#define DEFAULT_COLOR_GREEN 0 +#define DEFAULT_COLOR_BLUE 255 + +#define DEFAULT_MIN_INTENSITY 10 /* In percent. */ +#define DEFAULT_MAX_INTENSITY 100 + +#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */ + +#define DIR_NONE 0 /* Direction the levels can be changed: */ +#define DIR_TOP 1 +#define DIR_TOP_RIGHT 2 +#define DIR_RIGHT 3 +#define DIR_BOT_RIGHT 4 +#define DIR_BOT 5 +#define DIR_BOT_LEFT 6 +#define DIR_LEFT 7 +#define DIR_TOP_LEFT 8 + +#define DEFAULT_DIR "T" /* TOP (North) direction. */ + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module \t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifBG q%- d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-"; +#endif /* SYSV */ + +static int + MaximumIntensity = DEFAULT_MAX_INTENSITY, /* In percent. */ + MinimumIntensity = DEFAULT_MIN_INTENSITY, + NumLevels = DEFAULT_NUM_LEVELS, + ImageWidth = DEFAULT_WIDTH, + ImageHeight = DEFAULT_HEIGHT, + Direction; +static unsigned int + RedColor = DEFAULT_COLOR_RED, + GreenColor = DEFAULT_COLOR_GREEN, + BlueColor = DEFAULT_COLOR_BLUE; + +static void QuitGifError(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + unsigned int Ratio; + int i, j, l, LevelHeight, LevelWidth, Error, LogNumLevels, FlipDir, + Accumulator, StartX, StepX, Count = 0, DoAllMaximum = FALSE, + DirectionFlag = FALSE, LevelsFlag = FALSE, ColorFlag = FALSE, + MinFlag = FALSE, MaxFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE; + GifPixelType Color; + char *DirectionStr = DEFAULT_DIR; + GifRowType Line; + GifColorType *ColorMap; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &DirectionFlag, &DirectionStr, &LevelsFlag, &NumLevels, + &ColorFlag, &RedColor, &GreenColor, &BlueColor, + &MinFlag, &MinimumIntensity, &MaxFlag, &MaximumIntensity, + &SizeFlag, &ImageWidth, &ImageHeight, + &HelpFlag)) != FALSE) { + GAPrintErrMsg(Error); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* Make sure intensities are in the right range: */ + if (MinimumIntensity < 0 || MinimumIntensity > 100 || + MaximumIntensity < 0 || MaximumIntensity > 100) + GIF_EXIT("Intensities (-m or -M options) are not in [0..100] range (percent)."); + + /* Convert DirectionStr to our local representation: */ + Direction = DIR_NONE; + FlipDir = FALSE; + for (i = 0; i < strlen(DirectionStr); i++) /* Make sure its upper case. */ + if (islower(DirectionStr[i])) + DirectionStr[i] = toupper(DirectionStr[i]); + + switch(DirectionStr[0]) { + case 'T': /* Top or North */ + case 'N': + if (strlen(DirectionStr) < 2) + Direction = DIR_TOP; + else + switch(DirectionStr[1]) { + case 'R': + case 'E': + Direction = DIR_TOP_RIGHT; + break; + case 'L': + case 'W': + Direction = DIR_TOP_LEFT; + FlipDir = TRUE; + break; + } + break; + case 'R': /* Right or East */ + case 'E': + Direction = DIR_RIGHT; + break; + case 'B': /* Bottom or South */ + case 'S': + if (strlen(DirectionStr) < 2) { + Direction = DIR_BOT; + FlipDir = TRUE; + } + else + switch(DirectionStr[1]) { + case 'R': + case 'E': + Direction = DIR_BOT_RIGHT; + break; + case 'L': + case 'W': + Direction = DIR_BOT_LEFT; + FlipDir = TRUE; + break; + } + break; + case 'L': /* Left or West */ + case 'W': + Direction = DIR_LEFT; + FlipDir = TRUE; + break; + } + if (Direction == DIR_NONE) + GIF_EXIT("Direction requested (-d option) is wierd!"); + + /* We are going to handle only TOP, TOP_RIGHT, RIGHT, BOT_RIGHT so flip */ + /* the complement cases (TOP <-> BOT for example) by flipping the */ + /* Color i with color (NumLevels - i - 1). */ + if (FlipDir) { + switch (Direction) { + case DIR_BOT: + Direction = DIR_TOP; + break; + case DIR_BOT_LEFT: + Direction = DIR_TOP_RIGHT; + break; + case DIR_LEFT: + Direction = DIR_RIGHT; + break; + case DIR_TOP_LEFT: + Direction = DIR_BOT_RIGHT; + break; + } + } + + /* If binary mask is requested (special case): */ + if (MinimumIntensity == 100 && MaximumIntensity == 100 && NumLevels == 2) { + MinimumIntensity = 0; + DoAllMaximum = TRUE; + Direction = DIR_RIGHT; + } + + /* Make sure colors are in the right range: */ + if (RedColor > 255 || GreenColor > 255 || BlueColor > 255) + GIF_EXIT("Colors are not in the ragne [0..255]."); + + /* Make sure number of levels is power of 2 (up to 8 bits per pixel). */ + for (i = 1; i < 8; i++) if (NumLevels == (1 << i)) break; + if (i == 8) GIF_EXIT("#Lvls (-l option) is not power of 2."); + LogNumLevels = i; + + /* Open stdout for the output file: */ + if ((GifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFile); + + /* Dump out screen description with given size and generated color map: */ + if ((ColorMap = (GifColorType *) malloc(NumLevels * sizeof(GifColorType))) + == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 1; i <= NumLevels; i++) { + /* Ratio will be in the range of 0..100 for required intensity: */ + Ratio = (MaximumIntensity * (i * (256 / NumLevels)) + + MinimumIntensity * ((NumLevels - i) * (256 / NumLevels))) / + 256; + ColorMap[i-1].Red = (RedColor * Ratio) / 100; + ColorMap[i-1].Green = (GreenColor * Ratio) / 100; + ColorMap[i-1].Blue = (BlueColor * Ratio) / 100; + } + if (EGifPutScreenDesc(GifFile, + ImageWidth, ImageHeight, LogNumLevels, 0, LogNumLevels, ColorMap) + == GIF_ERROR) + QuitGifError(GifFile); + + /* Dump out the image descriptor: */ + if (EGifPutImageDesc(GifFile, + 0, 0, ImageWidth, ImageHeight, FALSE, LogNumLevels, NULL) == GIF_ERROR) + QuitGifError(GifFile); + + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + /* Allocate one scan line twice as big as image is as we are going to */ + /* shift along it, while we dump the scan lines: */ + if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth * 2)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + if (Direction == DIR_TOP) { + /* We must evaluate the line each time level is changing: */ + LevelHeight = ImageHeight / NumLevels; + for (Color = NumLevels, i = l = 0; i < ImageHeight; i++) { + if (i == l) { + /* Time to update the line to next color level: */ + if (Color != 0) Color--; + for (j = 0; j < ImageWidth; j++) + Line[j] = (FlipDir ? NumLevels - Color - 1 : Color); + l += LevelHeight; + } + if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Count++); + } + } + else if (Direction == DIR_RIGHT) { + /* We pre-prepare the scan lines as going from color zero to maximum */ + /* color and dump the same scan line Height times: */ + /* Note this case should handle the Boolean Mask special case. */ + LevelWidth = ImageWidth / NumLevels; + if (DoAllMaximum) { + /* Special case - do all in maximum color: */ + for (i = 0; i < ImageWidth; i++) Line[i] = 1; + } + else { + for (Color = i = 0, l = LevelWidth; i < ImageWidth; i++, l--) { + if (l == 0) { + l = LevelWidth; + if (Color < NumLevels - 1) Color++; + } + Line[i] = (FlipDir ? NumLevels - Color - 1 : Color); + } + } + + for (i = 0; i < ImageHeight; i++) { + if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Count++); + } + } + else { + /* We are in one of the TOP_RIGHT, BOT_RIGHT cases: we will */ + /* initialize the Line with its double ImageWidth length from the */ + /* minimum intensity to the maximum intensity and shift along it */ + /* while we go along the image height. */ + LevelWidth = ImageWidth * 2 / NumLevels; + for (Color = i = 0, l = LevelWidth; i < ImageWidth * 2; i++, l--) { + if (l == 0) { + l = LevelWidth; + if (Color < NumLevels - 1) Color++; + } + Line[i] = (FlipDir ? NumLevels - Color - 1 : Color); + } + /* We need to implement a DDA to know how much to shift Line while */ + /* we go down along image height. we set the parameters for it now: */ + Accumulator = 0; + switch(Direction) { + case DIR_TOP_RIGHT: + StartX = ImageWidth; + StepX = -1; + break; + case DIR_BOT_RIGHT: + default: + StartX = 0; + StepX = 1; + break; + } + + /* Time to dump information out: */ + for (i = 0; i < ImageHeight; i++) { + if (EGifPutLine(GifFile, &Line[StartX], ImageWidth) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Count++); + if ((Accumulator += ImageWidth) > ImageHeight) { + while (Accumulator > ImageHeight) { + Accumulator -= ImageHeight; + StartX += StepX; + } + if (Direction < 0) Direction = 0; + if (Direction > ImageWidth) Direction = ImageWidth; + } + } + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) + QuitGifError(GifFile); +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFile) +{ + PrintGifError(); + if (GifFile != NULL) EGifCloseFile(GifFile); + exit(1); +} diff --git a/G/UTIL/GIFCLIP.C b/G/UTIL/GIFCLIP.C new file mode 100644 index 0000000..d195a0a --- /dev/null +++ b/G/UTIL/GIFCLIP.C @@ -0,0 +1,256 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to clip an image and dump out only portion of it. * +* Options: * +* -q : quite printing mode. * +* -i left top width bottom : clipping information for first image. * +* -n n left top width bottom : clipping information for nth image. * +* -h : on line help * +****************************************************************************** +* History: * +* 8 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifClip" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifClip q%- i%-Xmin|Ymin|Xmax|Ymax!d!d!d!d n%-n|Xmin|Ymin|Xmax|Ymax!d!d!d!d!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- i%-Xmin|Ymin|Xmax|Ymax!d!d!d!d n%-n|Xmin|Ymin|Xmax|Ymax!d!d!d!d!d h%- GifFile!*s"; +#endif /* SYSV */ + +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, Error, NumFiles, ExtCode, CodeSize, ImageNum = 0, + ImageFlag = FALSE, ImageNFlag = FALSE, ImageN, ImageX1, ImageY1, + ImageX2, ImageY2, ImageWidth, HelpFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension, *CodeBlock; + char **FileName = NULL; + GifRowType Line; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + /* Same image dimension vars for both Image & ImageN as only one allowed.*/ + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &ImageFlag, &ImageX1, &ImageY1, &ImageX2, &ImageY2, + &ImageNFlag, &ImageN, &ImageX1, &ImageY1, &ImageX2, &ImageY2, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* Test to make sure exactly one of ImageFlag & ImageNFlag is set: */ + if ((ImageFlag && ImageNFlag) || (!ImageFlag && !ImageNFlag)) { + GIF_MESSAGE("Exactly one of [-i ...] && [-n ...] please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + if (ImageFlag) ImageN = 1; /* Its first image we are after. */ + + /* Make sure the first coordinates of clipping box are smaller: */ + if (ImageX1 > ImageX2) { + i = ImageX1; + ImageX1 = ImageX2; + ImageX2 = i; + } + if (ImageY1 > ImageY2) { + i = ImageX1; + ImageY1 = ImageY2; + ImageY2 = i; + } + ImageWidth = ImageX2 - ImageX1 + 1; /* Width of clipped image. */ + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* And dump out exactly same screen information: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (++ImageNum == ImageN) { + /* We can handle only non interlaced images here: */ + if (GifFileIn -> IInterlace) + GIF_EXIT("Image to clip is interlaced - use GifInter first."); + + /* This is the image we should clip - test sizes and */ + /* dump out new clipped screen descriptor if o.k. */ + if (GifFileIn -> IWidth <= ImageX2 || + GifFileIn -> IHeight <= ImageY2) + GIF_EXIT("Image is smaller than given clip dimensions."); + + /* Put the image descriptor to out file: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + ImageWidth, ImageY2 - ImageY1 + 1, + FALSE, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* o.k. - read the image and clip it: */ + Line = (GifRowType) malloc(GifFileIn -> IWidth * + sizeof(GifPixelType)); + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ImageNum, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight); + + /* Skip lines below ImageY1: */ + for (i = 0; i < ImageY1; i++) { + if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + GifQprintf("\b\b\b\b%-4d", i); + } + + /* Clip the lines from ImageY1 to ImageY2 (to X1 - X2): */ + for (i = ImageY1; i <= ImageY2; i++) { + if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutLine(GifFileOut, &Line[ImageX1], + ImageWidth) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + GifQprintf("\b\b\b\b%-4d", i); + } + + /* Skip lines above ImageY2: */ + for (i = ImageY2 + 1; i < GifFileIn -> IHeight; i++) { + if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + GifQprintf("\b\b\b\b%-4d", i); + } + + free((char *) Line); + } + else { + /* Copy the image as is (we dont modify this one): */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Now read image itself in decoded form as we dont */ + /* really care what is there, and this is much faster. */ + if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR + || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || + EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_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); +} + diff --git a/G/UTIL/GIFCLRMP.C b/G/UTIL/GIFCLRMP.C new file mode 100644 index 0000000..2ed25cb --- /dev/null +++ b/G/UTIL/GIFCLRMP.C @@ -0,0 +1,279 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to modify GIF file color map(s). Images are not modified at all. * +* Options: * +* -q : quite printing mode. * +* -s : save screen color map (unless -i - see below), to stdout. * +* -l colormap.file : substitute given colormap.file colormap into screen * +* colormap (unless -i - see below). * +* -g correction : apply gamma correction to the screen colormap (unless -i - * +* see below). * +* -i n : select image number n color map instead of screen map for above * +* operations (n = 1 for first image). * +* -h : on line help. * +* All color maps are ascii text files, with one line per color of the * +* form: index, Red color, Green color, Blue color - all in the range 0..255. * +* All color maps should be in the exact same length. * +****************************************************************************** +* History: * +* 17 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifClrMp" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifClrMp q%- s%- l%-ColorMapFile!s g%-Gamma!F i%-Image#!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- s%- l%-ColorMapFile!s g%-Gamma!F i%-Image#!d h%- GifFile!*s"; +#endif /* SYSV */ + +static int + SaveFlag = FALSE, + LoadFlag = FALSE, + GammaFlag = FALSE; +static + double Gamma = 1.0; +static + FILE *ColorFile = NULL; + + +static void ModifyColorMap(GifColorType *ColorMap, int BitsPerPixel); +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, ExtCode, CodeSize, ImageNum = 0, + ImageNFlag = FALSE, ImageN, HelpFlag = FALSE, HasGIFOutput; + GifRecordType RecordType; + GifByteType *Extension, *CodeBlock; + char **FileName = NULL, *ColorFileName; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &SaveFlag, &LoadFlag, &ColorFileName, + &GammaFlag, &Gamma, &ImageNFlag, &ImageN, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (SaveFlag && LoadFlag || SaveFlag && GammaFlag || LoadFlag && GammaFlag) + GIF_EXIT("Can not handle more than one of -s -l or -g at the same time."); + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + if (SaveFlag) { + /* We are dumping out the color map as text file to stdout: */ + ColorFile = stdout; + } + else if (LoadFlag) { + /* We are loading new color map from specified file: */ + if ((ColorFile = fopen(ColorFileName, "rt")) == NULL) + GIF_EXIT("Failed to open specified color map file."); + } + + if ((HasGIFOutput = (LoadFlag || GammaFlag)) != 0) { + /* Open stdout for GIF output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + if (!ImageNFlag) { + /* We are suppose to modify the screen color map, so do it: */ + ModifyColorMap(GifFileIn -> SColorMap, GifFileIn -> SBitsPerPixel); + if (!HasGIFOutput) { + /* We can quit here, as we have the color map: */ + if (GifFileIn != NULL) DGifCloseFile(GifFileIn); + fclose(ColorFile); + exit(0); + } + } + /* And dump out its new possible repositioned screen information: */ + if (HasGIFOutput) + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (++ImageNum == ImageN && ImageNFlag) { + /* We are suppose to modify this image color map, do it: */ + ModifyColorMap(GifFileIn -> SColorMap, + GifFileIn -> SBitsPerPixel); + if (!HasGIFOutput) { + /* We can quit here, as we have the color map: */ + if (GifFileIn != NULL) DGifCloseFile(GifFileIn); + fclose(ColorFile); + exit(0); + } + } + if (HasGIFOutput) + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (HasGIFOutput) + if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) { + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (HasGIFOutput) + if (EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (HasGIFOutput) + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (HasGIFOutput) + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); +} + +/****************************************************************************** +* Modify the given colormap according to global variables setting. * +******************************************************************************/ +static void ModifyColorMap(GifColorType *ColorMap, int BitsPerPixel) +{ + int i, Dummy, Red, Green, Blue; + double Gamma1; + + if (SaveFlag) { + /* Save this color map to ColorFile: */ + for (i = 0; i < (1 << BitsPerPixel); i++) + fprintf(ColorFile, "%3d %3d %3d %3d\n", i, + ColorMap[i].Red, ColorMap[i].Green, ColorMap[i].Blue); + } + else if (LoadFlag) { + /* Read the color map in ColorFile into this color map: */ + for (i = 0; i < (1 << BitsPerPixel); i++) { + if (feof(ColorFile)) + GIF_EXIT("Color file to load color map from, too small."); + fscanf(ColorFile, "%3d %3d %3d %3d\n", &Dummy, &Red, &Green, &Blue); + ColorMap[i].Red = Red; + ColorMap[i].Green = Green; + ColorMap[i].Blue = Blue; + } + } + else if (GammaFlag) { + /* Apply gamma correction to this color map: */ + Gamma1 = 1.0 / Gamma; + for (i = 0; i < (1 << BitsPerPixel); i++) { + ColorMap[i].Red = + ((int) (255 * pow(ColorMap[i].Red / 255.0, Gamma1))); + ColorMap[i].Green = + ((int) (255 * pow(ColorMap[i].Green / 255.0, Gamma1))); + ColorMap[i].Blue = + ((int) (255 * pow(ColorMap[i].Blue / 255.0, Gamma1))); + } + } + else + GIF_EXIT("Nothing to do!"); +} + +/****************************************************************************** +* 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); +} + diff --git a/G/UTIL/GIFCOMB.C b/G/UTIL/GIFCOMB.C new file mode 100644 index 0000000..46fac46 --- /dev/null +++ b/G/UTIL/GIFCOMB.C @@ -0,0 +1,322 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to combine 2 GIF images into single one, using optional mask GIF * +* file. Result colormap will be the union of the two images colormaps. * +* Both images should have exactly the same size, although they may be mapped * +* differently on screen. Only First GIF screen descriptor info. is used. * +* Options: * +* -q : quite printing mode. * +* -m mask : optional boolean image, defines where second GIF should be used. * +* -h : on line help. * +****************************************************************************** +* History: * +* 12 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* _MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifComb" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifComb q%- m%-MaskGIFFile!s h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- m%-MaskGIFFile!s h%- GifFile!*s"; +#endif /* SYSV */ + +static int ReadUntilImage(GifFileType *GifFile); +static int UnionColorMap(GifColorType *ColorIn1, int ColorIn1Size, + GifColorType *ColorIn2, int ColorIn2Size, + GifColorType **ColorUnionPtr, int *ColorUnionSize, + GifPixelType ColorTransIn2[]); +static void QuitGifError(GifFileType *GifFileIn1, GifFileType *GifFileIn2, + GifFileType *GifMaskFile, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Size, ColorUnionSize, + ColorIn1Size = 0, ColorIn2Size = 0, + MaskFlag = FALSE, HelpFlag = FALSE; + char **FileName = NULL, *MaskFileName; + GifPixelType ColorTransIn2[256]; + GifRowType LineIn1 = NULL, LineIn2 = NULL, LineMask = NULL, LineOut = NULL; + GifColorType *ColorIn1 = NULL, *ColorIn2 = NULL, *ColorUnion; + GifFileType *GifFileIn1 = NULL, *GifFileIn2 = NULL, *GifMaskFile = NULL, + *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &MaskFlag, &MaskFileName, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles != 2 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles != 2) + GIF_MESSAGE("Error in command line parsing - two GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* Open all input files (two GIF to combine, and optional mask): */ + if ((GifFileIn1 = DGifOpenFileName(FileName[0])) == NULL || + (GifFileIn2 = DGifOpenFileName(FileName[1])) == NULL || + (MaskFlag && (GifMaskFile = DGifOpenFileName(MaskFileName)) == NULL)) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + + if (ReadUntilImage(GifFileIn1) == GIF_ERROR || + ReadUntilImage(GifFileIn2) == GIF_ERROR || + (MaskFlag && ReadUntilImage(GifMaskFile) == GIF_ERROR)) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + + if (GifFileIn1 -> IWidth != GifFileIn2 -> IWidth || + GifFileIn2 -> IHeight != GifFileIn2 -> IHeight || + (MaskFlag && (GifFileIn1 -> IWidth != GifMaskFile -> IWidth || + GifFileIn1 -> IHeight != GifMaskFile -> IHeight))) + GIF_EXIT("Given GIF files have different image dimensions."); + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + + Size = sizeof(GifPixelType) * GifFileIn1 -> IWidth; + if ((LineIn1 = (GifRowType) malloc(Size)) == NULL || + (LineIn2 = (GifRowType) malloc(Size)) == NULL || + (MaskFlag && (LineMask = (GifRowType) malloc(Size)) == NULL) || + (LineOut = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + if (GifFileIn1 -> IColorMap) { + ColorIn1 = GifFileIn1 -> IColorMap; + ColorIn1Size = 1 << GifFileIn1 -> IBitsPerPixel; + } + else if (GifFileIn1 -> SColorMap) { + ColorIn1 = GifFileIn1 -> SColorMap; + ColorIn1Size = 1 << GifFileIn1 -> SBitsPerPixel; + } + else + GIF_EXIT("Neither Screen nor Image color map exists - GIF file 1."); + + if (GifFileIn2 -> IColorMap) { + ColorIn2 = GifFileIn2 -> IColorMap; + ColorIn2Size = 1 << GifFileIn2 -> IBitsPerPixel; + } + else if (GifFileIn2 -> SColorMap) { + ColorIn2 = GifFileIn2 -> SColorMap; + ColorIn2Size = 1 << GifFileIn2 -> SBitsPerPixel; + } + else + GIF_EXIT("Neither Screen nor Image color map exists - GIF file 2."); + + /* Create union of the two given color maps. ColorIn1 will be copied as */ + /* is while ColorIn2 will be mapped using ColorTransIn2 table. */ + /* ColorUnion is allocated by the procedure itself. */ + if (UnionColorMap(ColorIn1, ColorIn1Size, ColorIn2, ColorIn2Size, + &ColorUnion, &ColorUnionSize, ColorTransIn2) == GIF_ERROR) + GIF_EXIT("Unioned color map is two big (>256 colors)."); + + /* Dump out new image and screen descriptors: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn1 -> SWidth, GifFileIn1 -> SHeight, + ColorUnionSize, GifFileIn1 -> SBackGroundColor, + ColorUnionSize, ColorUnion) == GIF_ERROR) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + free((char *) ColorUnion); /* We dont need this any more... */ + + if (EGifPutImageDesc(GifFileOut, + GifFileIn1 -> ILeft, GifFileIn1 -> ITop, + GifFileIn1 -> IWidth, GifFileIn1 -> IHeight, + GifFileIn1 -> IInterlace, GifFileIn1 -> IBitsPerPixel, NULL) == GIF_ERROR) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + + + /* Time to do it: read 2 scan lines from 2 files (and optionally from */ + /* the mask file, merge them and them result out. Do it Height times: */ + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFileOut -> ILeft, GifFileOut -> ITop, + GifFileOut -> IWidth, GifFileOut -> IHeight); + for (i = 0; i < GifFileIn1 -> IHeight; i++) { + if (DGifGetLine(GifFileIn1, LineIn1, GifFileIn1 -> IWidth) == GIF_ERROR || + DGifGetLine(GifFileIn2, LineIn2, GifFileIn2 -> IWidth) == GIF_ERROR || + (MaskFlag && + DGifGetLine(GifMaskFile, LineMask, GifMaskFile -> IWidth) + == GIF_ERROR)) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + if (MaskFlag) { + /* Every time Mask has non background color, use LineIn1 pixel, */ + /* otherwise use LineIn2 pixel instead. */ + for (j = 0; j < GifFileIn1 -> IWidth; j++) { + if (LineMask[j] != GifMaskFile -> SBackGroundColor) + LineOut[j] = LineIn1[j]; + else + LineOut[j] = ColorTransIn2[LineIn2[j]]; + } + } + else { + /* Every time Color of Image 1 is equal to background - take it */ + /* From Image 2 instead of the background. */ + for (j = 0; j < GifFileIn1 -> IWidth; j++) { + if (LineIn1[j] != GifFileIn1 -> SBackGroundColor) + LineOut[j] = LineIn1[j]; + else + LineOut[j] = ColorTransIn2[LineIn2[j]]; + } + } + if (EGifPutLine(GifFileOut, LineOut, GifFileOut -> IWidth) + == GIF_ERROR) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); + GifQprintf("\b\b\b\b%-4d", i); + } + + if (DGifCloseFile(GifFileIn1) == GIF_ERROR || + DGifCloseFile(GifFileIn2) == GIF_ERROR || + EGifCloseFile(GifFileOut) == GIF_ERROR || + (MaskFlag && DGifCloseFile(GifMaskFile) == GIF_ERROR)) + QuitGifError(GifFileIn1, GifFileIn2, GifMaskFile, GifFileOut); +} + +/****************************************************************************** +* Read until first image in GIF file is detected and read its descriptor. * +******************************************************************************/ +static int ReadUntilImage(GifFileType *GifFile) +{ + int ExtCode; + GifRecordType RecordType; + GifByteType *Extension; + + /* Scan the content of the GIF file, until image descriptor is detected: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) + return GIF_ERROR; + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + return DGifGetImageDesc(GifFile); + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) + return GIF_ERROR; + + while (Extension != NULL) + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) + return GIF_ERROR; + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + return GIF_ERROR; /* We should be here - no image was found! */ +} + +/****************************************************************************** +* Create union of the two given color maps and return it. If result can not * +* fit into 256 colors, GIF_ERROR is returned, GIF_OK otherwise. * +* ColorIn1 is copied as it to ColorUnion, while colors from ColorIn2 are * +* copied iff they dont exists before. ColorTransIn2 is used to map old * +* ColorIn2 into ColorUnion color map table. * +******************************************************************************/ +static int UnionColorMap(GifColorType *ColorIn1, int ColorIn1Size, + GifColorType *ColorIn2, int ColorIn2Size, + GifColorType **ColorUnionPtr, int *ColorUnionSize, + GifPixelType ColorTransIn2[]) +{ + int i, j, CrntSlot; + GifColorType *ColorUnion; + + /* Allocate table which will hold result for sure: */ + *ColorUnionPtr = ColorUnion = (GifColorType *) malloc(sizeof(GifColorType) + * (ColorIn1Size > ColorIn2Size ? ColorIn1Size : ColorIn2Size) * 2); + + /* Copy ColorIn1 to ColorUnionSize; */ + for (i = 0; i < ColorIn1Size; i++) ColorUnion[i] = ColorIn1[i]; + CrntSlot = ColorIn1Size; /* Current Empty slot. */ + + /* Copy ColorIn2 to ColorUnionSize (use old colors if exists): */ + for (i = 0; i < ColorIn2Size && CrntSlot<=256; i++) { + /* Let see if this color already exists: */ + for (j = 0; j < ColorIn1Size; j++) { + /* If memcmp does not exists for you, use the following: */ + /* + if (ColorIn1[j].Red == ColorIn2[i].Red && + ColorIn1[j].Green == ColorIn2[i].Green && + ColorIn1[j].Blue == ColorIn2[i].Blue) break; + */ + if (memcmp(&ColorIn1[j], &ColorIn2[i], 3) == 0) break; + } + if (j < ColorIn1Size) { + /* We found this color aleardy exists in ColorIn1: */ + ColorTransIn2[i] = j; + } + else { + /* Its new - copy it to a new slot: */ + ColorUnion[CrntSlot] = ColorIn2[i]; + ColorTransIn2[i] = CrntSlot++; + } + } + + if (CrntSlot > 256) return GIF_ERROR; + + /* Complete the color map to a power of two: */ + for (i = 1; i <= 8; i++) if ((1 << i) >= CrntSlot) break; + for (j = CrntSlot; j < (1 << i); j++) + ColorUnion[j].Red = ColorUnion[j].Green = ColorUnion[j].Blue = 0; + + *ColorUnionSize = i; + + return GIF_OK; +} + +/****************************************************************************** +* Close both input and output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFileIn1, GifFileType *GifFileIn2, + GifFileType *GifMaskFile, GifFileType *GifFileOut) +{ + PrintGifError(); + if (GifFileIn1 != NULL) DGifCloseFile(GifFileIn1); + if (GifFileIn2 != NULL) DGifCloseFile(GifFileIn2); + if (GifMaskFile != NULL) DGifCloseFile(GifMaskFile); + if (GifFileOut != NULL) EGifCloseFile(GifFileOut); + exit(1); +} diff --git a/G/UTIL/GIFDEBUG.DSK b/G/UTIL/GIFDEBUG.DSK new file mode 100644 index 0000000..c2c13ef Binary files /dev/null and b/G/UTIL/GIFDEBUG.DSK differ diff --git a/G/UTIL/GIFDEBUG.PRJ b/G/UTIL/GIFDEBUG.PRJ new file mode 100644 index 0000000..c141fe1 Binary files /dev/null and b/G/UTIL/GIFDEBUG.PRJ differ diff --git a/G/UTIL/GIFFIX.C b/G/UTIL/GIFFIX.C new file mode 100644 index 0000000..0936ca2 --- /dev/null +++ b/G/UTIL/GIFFIX.C @@ -0,0 +1,215 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to attempt and fix broken GIF images. Currently fix the following: * +* 1. EOF terminates before end of image size (adds black in the end). * +* Options: * +* -q : quite printing mode. * +* -h : on line help * +****************************************************************************** +* History: * +* 5 May 91 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifFix" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifFix q%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0; + +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, ExtCode, ColorMapSize, Row, Col, Width, Height, + DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType LineBuffer; + GifColorType *ColorMap; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* Dump out exactly same screen information: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + if ((LineBuffer = (GifRowType) malloc(GifFileIn -> SWidth)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (GifFileIn -> IInterlace) + GIF_EXIT("Cannt fix interlaced images."); + + Row = GifFileIn -> ITop; /* Image Position relative to Screen. */ + Col = GifFileIn -> ILeft; + Width = GifFileIn -> IWidth; + Height = GifFileIn -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + + /* Put the image descriptor to out file: */ + if (EGifPutImageDesc(GifFileOut, Col, Row, Width, Height, + FALSE, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Find the darkest color in color map to use as a filler. */ + ColorMap = (GifFileIn -> IColorMap ? GifFileIn -> IColorMap : + GifFileIn -> SColorMap); + ColorMapSize = 1 << (GifFileIn -> IColorMap ? + GifFileIn -> IBitsPerPixel : + GifFileIn -> SBitsPerPixel); + for (i = 0; i < ColorMapSize; i++) { + j = ((int) ColorMap[i].Red) * 30 + + ((int) ColorMap[i].Green) * 59 + + ((int) ColorMap[i].Blue) * 11; + if (j < ColorIntens) { + ColorIntens = j; + DarkestColor = i; + } + } + + /* Load the image, and dump it. */ + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFileIn, LineBuffer, Width) + == GIF_ERROR) break; + if (EGifPutLine(GifFileOut, LineBuffer, Width) + == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); + } + + if (i < Height) { + fprintf(stderr, "\nFollowing error occured (and ignored):"); + PrintGifError(); + + /* Fill in with the darkest color in color map. */ + for (j = 0; j < Width; j++) + LineBuffer[j] = DarkestColor; + for (; i < Height; i++) + if (EGifPutLine(GifFileOut, LineBuffer, Width) + == GIF_ERROR) QuitGifError(GifFileIn, GifFileOut); + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); +} + +/****************************************************************************** +* Close both input and output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut) +{ + fprintf(stderr, "\nFollowing unrecoverable error occured:"); + PrintGifError(); + if (GifFileIn != NULL) DGifCloseFile(GifFileIn); + if (GifFileOut != NULL) EGifCloseFile(GifFileOut); + exit(1); +} diff --git a/G/UTIL/GIFFLIP.C b/G/UTIL/GIFFLIP.C new file mode 100644 index 0000000..c84858b --- /dev/null +++ b/G/UTIL/GIFFLIP.C @@ -0,0 +1,341 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to rotate image 90 degrees to the right/left or flip the image * +* horizintally/vertically (mirror). * +* Options: * +* -q : quite printing mode. * +* -r : rotate 90 degrees to the right (default). * +* -l : rotate 90 degrees to the left. * +* -x : Mirror the image horizontally (first line switch places with last). * +* -y : Mirror the image vertically (first column switch places with last). * +* -h : on line help * +****************************************************************************** +* History: * +* 10 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifFlip" + +#define FLIP_NONE 0 +#define FLIP_RIGHT 1 +#define FLIP_LEFT 2 +#define FLIP_HORIZ 3 +#define FLIP_VERT 4 + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifFlip q%- r%- l%- x%- y%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- r%- l%- x%- y%- h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0; + +static int LoadImage(GifFileType *GifFile, GifRowType **ImageBuffer); +static int DumpImage(GifFileType *GifFile, GifRowType *ImageBuffer, + int Width, int Height, int FlipDirection); +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, Error, NumFiles, ExtCode, FlipDirection = FLIP_RIGHT, + RightFlag = FALSE, LeftFlag = FALSE, + HorizFlag = FALSE, VertFlag = FALSE, HelpFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ImageBuffer; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &RightFlag, &LeftFlag, &HorizFlag, &VertFlag, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if ((i = (RightFlag != 0) + (LeftFlag != 0) + + (HorizFlag != 0) + (VertFlag != 0)) > 1) + GIF_EXIT("Only one of -r, -l, -x, -y please."); + if (i == 0) + FlipDirection = FLIP_RIGHT; /* Make it the default. */ + else { + if (RightFlag) FlipDirection = FLIP_RIGHT; + if (LeftFlag) FlipDirection = FLIP_LEFT; + if (HorizFlag) FlipDirection = FLIP_HORIZ; + if (VertFlag) FlipDirection = FLIP_VERT; + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + if (RightFlag || LeftFlag) { + /* Dump out same screen information, but flip Screen Width/Height: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SHeight, GifFileIn -> SWidth, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Dump out exactly same screen information: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (GifFileIn -> IInterlace) + GIF_EXIT("Cannt flip interlaced images - use GifInter first."); + + /* Put the image descriptor to out file: */ + if (RightFlag) { + /* Rotate to the right: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> SHeight - GifFileIn -> IHeight - + GifFileIn -> ITop, + GifFileIn -> ILeft, + GifFileIn -> IHeight, GifFileIn -> IWidth, + FALSE, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + else if (LeftFlag) { + /* Rotate to the left: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ITop, + GifFileIn -> SWidth - GifFileIn -> IWidth - + GifFileIn -> ILeft, + GifFileIn -> IHeight, GifFileIn -> IWidth, + FALSE, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* No rotation - only flipping vert. or horiz.: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + FALSE, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Load the image (either Interlaced or not), and dump it */ + /* fliped as requrested by Flags: */ + if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (DumpImage(GifFileOut, ImageBuffer, GifFileIn -> IWidth, + GifFileIn -> IHeight, FlipDirection) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); +} + +/****************************************************************************** +* Routine to read Image out. The image can be Non interlaced only. * +* The memory required to hold the image is allocate by the routine itself. * +* Return GIF_OK if succesful, GIF_ERROR otherwise. * +******************************************************************************/ +static int LoadImage(GifFileType *GifFile, GifRowType **ImageBufferPtr) +{ + int Size, i; + GifRowType *ImageBuffer; + + /* Allocate the image as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + if ((ImageBuffer = (GifRowType *) + malloc(GifFile -> IHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> IWidth * sizeof(GifPixelType);/* One row size in bytes.*/ + for (i = 0; i < GifFile -> IHeight; i++) { + /* Allocate the rows: */ + if ((ImageBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + } + + *ImageBufferPtr = ImageBuffer; + + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + for (i = 0; i < GifFile -> IHeight; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, ImageBuffer[i], GifFile -> IWidth) + == GIF_ERROR) return GIF_ERROR; + } + + return GIF_OK; +} + +/****************************************************************************** +* Routine to dump image out. The given Image buffer should always hold the * +* image sequencially, and Width & Height hold image dimensions BEFORE flip. * +* Image will be dumped according to FlipDirection. * +* Once dumped, the memory holding the image is freed. * +* Return GIF_OK if succesful, GIF_ERROR otherwise. * +******************************************************************************/ +static int DumpImage(GifFileType *GifFile, GifRowType *ImageBuffer, + int Width, int Height, int FlipDirection) +{ + int i, j, Count; + GifRowType Line; /* New scan line is copied to it. */ + + /* Allocate scan line that will fit both image width and height: */ + if ((Line = (GifRowType) malloc((Width > Height ? Width : Height) + * sizeof(GifPixelType))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + switch (FlipDirection) { + case FLIP_RIGHT: + for (Count = Width, i = 0; i < Width; i++) { + GifQprintf("\b\b\b\b%-4d", Count--); + for (j = 0; j < Height; j++) + Line[j] = ImageBuffer[Height - j - 1][i]; + if (EGifPutLine(GifFile, Line, Height) == GIF_ERROR) + return GIF_ERROR; + } + break; + case FLIP_LEFT: + for (i = Width - 1; i >= 0; i--) { + GifQprintf("\b\b\b\b%-4d", i + 1); + for (j = 0; j < Height; j++) + Line[j] = ImageBuffer[j][i]; + if (EGifPutLine(GifFile, Line, Height) == GIF_ERROR) + return GIF_ERROR; + } + break; + case FLIP_HORIZ: + for (i = Height - 1; i >= 0; i--) { + GifQprintf("\b\b\b\b%-4d", i); + if (EGifPutLine(GifFile, ImageBuffer[i], Width) == GIF_ERROR) + return GIF_ERROR; + } + break; + case FLIP_VERT: + for (Count = Height, i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", Count--); + for (j = 0; j < Width; j++) + Line[j] = ImageBuffer[i][Width - j - 1]; + if (EGifPutLine(GifFile, Line, Width) == GIF_ERROR) + return GIF_ERROR; + } + break; + } + + /* Free the memory used for this image, and the temporary scan line: */ + for (i = 0; i < Height; i++) free((char *) ImageBuffer[i]); + free((char *) ImageBuffer); + + free((char *) Line); + + return GIF_OK; +} + +/****************************************************************************** +* 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); +} diff --git a/G/UTIL/GIFHISTO.C b/G/UTIL/GIFHISTO.C new file mode 100644 index 0000000..fe4835c --- /dev/null +++ b/G/UTIL/GIFHISTO.C @@ -0,0 +1,264 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to create histogram of the colors used by the given GIF file. * +* Dumps out GIF file of constants size GIF_WIDTH by GIF_HEIGHT. * +* Options: * +* -q : quite printing mode. * +* -t : Dump out text instead of GIF - #Colors lines, each with #appearances. * +* -i W H : size of GIF image to generate. Colors of input GIF file are * +* spread homogeneously along Height, which better by dividable by the * +* number of colors in input image. * +* -n n : select image number to generate histogram to (1 by default). * +* -b : strip off background color count. * +* -h : on line help * +****************************************************************************** +* History: * +* 8 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifHisto" + +#define DEFAULT_HISTO_WIDTH 100 /* Histogram image diemnsions. */ +#define DEFAULT_HISTO_HEIGHT 256 +#define HISTO_BITS_PER_PIXEL 2 /* Size of bitmap for histogram GIF. */ + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifHisto q%- t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- t%- s%-Width|Height!d!d n%-ImageNumber!d b%- h%- GifFile!*s"; +#endif /* SYSV */ + +static int + ImageWidth = DEFAULT_HISTO_WIDTH, + ImageHeight = DEFAULT_HISTO_HEIGHT, + ImageN = 1; +static GifColorType + HistoColorMap[] = { /* Constant bit map for histograms: */ + { 0, 0, 0 }, + { 255, 0, 0 }, + { 0, 255, 0 }, + { 0, 0, 255 } + }; + +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Size, Error, NumFiles, ExtCode, CodeSize, NumColors = 2, Color, + Count, ImageNum = 0, TextFlag = FALSE, SizeFlag = FALSE, + ImageNFlag = FALSE, BackGroundFlag = FALSE, HelpFlag = FALSE; + long Scaler, Histogram[256]; + GifRecordType RecordType; + GifByteType *Extension, *CodeBlock; + char **FileName = NULL; + GifRowType Line; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + /* Same image dimension vars for both Image & ImageN as only one allowed */ + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &TextFlag, &SizeFlag, &ImageWidth, &ImageHeight, + &ImageNFlag, &ImageN, &BackGroundFlag, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + for (i = 0; i < 256; i++) Histogram[i] = 0; /* Reset counters. */ + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + if (GifFileIn -> IColorMap) + NumColors = (1 << GifFileIn -> IBitsPerPixel); + else if (GifFileIn -> SColorMap) + NumColors = (1 << GifFileIn -> SBitsPerPixel); + else + GIF_EXIT("Neither Screen nor Image color map exists."); + + if ((ImageHeight / NumColors) * NumColors != ImageHeight) + GIF_EXIT("Image height specified not dividable by #colors."); + + if (++ImageNum == ImageN) { + /* This is the image we should make histogram for: */ + Line = (GifRowType) malloc(GifFileIn -> IWidth * + sizeof(GifPixelType)); + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ImageNum, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight); + + for (i = 0; i < GifFileIn -> IHeight; i++) { + if (DGifGetLine(GifFileIn, Line, GifFileIn -> IWidth) + == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + for (j = 0; j < GifFileIn -> IWidth; j++) + Histogram[Line[j]]++; + GifQprintf("\b\b\b\b%-4d", i); + } + + free((char *) Line); + } + else { + /* Skip the image: */ + /* Now read image itself in decoded form as we dont */ + /* really care what is there, and this is much faster. */ + if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + /* We we requested to kill back ground count: */ + if (BackGroundFlag) Histogram[GifFileIn -> SBackGroundColor] = 0; + + if (DGifCloseFile(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + + /* We may required to dump out the histogram as text file: */ + if (TextFlag) { + for (i = 0; i < NumColors; i++) + printf("%12ld %3d\n", Histogram[i], i); + } + else { + /* Open stdout for the histogram output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* Dump out screen descriptor to fit histogram dimensions: */ + if (EGifPutScreenDesc(GifFileOut, + ImageWidth, ImageHeight, HISTO_BITS_PER_PIXEL, 0, + HISTO_BITS_PER_PIXEL, HistoColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Dump out image descriptor to fit histogram dimensions: */ + if (EGifPutImageDesc(GifFileOut, + 0, 0, ImageWidth, ImageHeight, + FALSE, HISTO_BITS_PER_PIXEL, NULL) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Prepare scan line for histogram file, and find scaler to scale */ + /* histogram to be between 0 and ImageWidth: */ + Line = (GifRowType) malloc(ImageWidth * sizeof(GifPixelType)); + for (Scaler = 0, i = 0; i < NumColors; i++) if (Histogram[i] > Scaler) + Scaler = Histogram[i]; + Scaler /= ImageWidth; + if (Scaler == 0) Scaler = 1; /* In case maximum is less than width. */ + + /* Dump out the image itself: */ + for (Count = ImageHeight, i = 0, Color = 1; i < NumColors; i++) { + if ((Size = Histogram[i] / Scaler) > ImageWidth) Size = ImageWidth; + for (j = 0; j < Size; j++) + Line[j] = Color; + for (j = Size; j < ImageWidth; j++) + Line[j] = GifFileOut -> SBackGroundColor; + + /* Move to next color: */ + if (++Color >= (1 << HISTO_BITS_PER_PIXEL)) Color = 1; + + /* Dump this histogram entry as many times as required: */ + for (j = 0; j < ImageHeight / NumColors; j++) { + if (EGifPutLine(GifFileOut, Line, ImageWidth) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + GifQprintf("\b\b\b\b%-4d", Count--); + } + } + + if (EGifCloseFile(GifFileOut) == GIF_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); +} diff --git a/G/UTIL/GIFINTER.C b/G/UTIL/GIFINTER.C new file mode 100644 index 0000000..4c30aa9 --- /dev/null +++ b/G/UTIL/GIFINTER.C @@ -0,0 +1,268 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to flip interlaced and non interlaced images in GIF files. * +* Options: * +* -q : quite printing mode. * +* -i : Force all images to be intelaced. * +* -s : Force all images to be sequencial (non interlaced). This is default. * +* -h : on line help * +****************************************************************************** +* History: * +* 5 Jul 89 - Version 1.0 by Gershon Elber. * +* 21 Dec 89 - Fix problems with -i and -s flags (Version 1.1). * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifInter" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifInter q%- i%- s%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- i%- s%- h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ImageNum = 0, + SequencialFlag = FALSE, + InterlacedFlag = FALSE, + HelpFlag = FALSE, + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ + +static int LoadImage(GifFileType *GifFile, GifRowType **ImageBuffer); +static int DumpImage(GifFileType *GifFile, GifRowType *ImageBuffer); +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, ExtCode; + GifRecordType RecordType; + GifByteType *Extension; + char **FileName = NULL; + GifRowType *ImageBuffer; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &InterlacedFlag, &SequencialFlag, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* And dump out exactly same screen information: */ + if (EGifPutScreenDesc(GifFileOut, + GifFileIn -> SWidth, GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Put the image descriptor to out file: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + InterlacedFlag, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Load the image (either Interlaced or not), and dump it as */ + /* defined in GifFileOut -> IInterlaced. */ + if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (DumpImage(GifFileOut, ImageBuffer) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); +} + +/****************************************************************************** +* Routine to read Image out. The image can be Interlaced or None interlaced. * +* The memory required to hold the image is allocate by the routine itself. * +* The image is always loaded sequencially into the buffer. * +* Return GIF_OK if succesful, GIF_ERROR otherwise. * +******************************************************************************/ +static int LoadImage(GifFileType *GifFile, GifRowType **ImageBufferPtr) +{ + int Size, i, j, Count; + GifRowType *ImageBuffer; + + /* Allocate the image as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + if ((ImageBuffer = (GifRowType *) + malloc(GifFile -> IHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> IWidth * sizeof(GifPixelType);/* One row size in bytes.*/ + for (i = 0; i < GifFile -> IHeight; i++) { + /* Allocate the rows: */ + if ((ImageBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + } + + *ImageBufferPtr = ImageBuffer; + + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = InterlacedOffset[i]; j < GifFile -> IHeight; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, ImageBuffer[j], GifFile -> IWidth) + == GIF_ERROR) return GIF_ERROR; + } + } + else { + for (i = 0; i < GifFile -> IHeight; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, ImageBuffer[i], GifFile -> IWidth) + == GIF_ERROR) return GIF_ERROR; + } + } + + return GIF_OK; +} + +/****************************************************************************** +* Routine to dump image out. The given Image buffer should always hold the * +* image sequencially. Image will be dumped according to IInterlaced flag in * +* GifFile structure. Once dumped, the memory holding the image is freed. * +* Return GIF_OK if succesful, GIF_ERROR otherwise. * +******************************************************************************/ +static int DumpImage(GifFileType *GifFile, GifRowType *ImageBuffer) +{ + int i, j, Count; + + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = GifFile -> IHeight, i = 0; i < 4; i++) + for (j = InterlacedOffset[i]; j < GifFile -> IHeight; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count--); + if (EGifPutLine(GifFile, ImageBuffer[j], GifFile -> IWidth) + == GIF_ERROR) return GIF_ERROR; + } + } + else { + for (Count = GifFile -> IHeight, i = 0; i < GifFile -> IHeight; i++) { + GifQprintf("\b\b\b\b%-4d", Count--); + if (EGifPutLine(GifFile, ImageBuffer[i], GifFile -> IWidth) + == GIF_ERROR) return GIF_ERROR; + } + } + + /* Free the m emory used for this image: */ + for (i = 0; i < GifFile -> IHeight; i++) free((char *) ImageBuffer[i]); + free((char *) ImageBuffer); + + return GIF_OK; +} + +/****************************************************************************** +* 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); +} diff --git a/G/UTIL/GIFINTO.C b/G/UTIL/GIFINTO.C new file mode 100644 index 0000000..feadde6 --- /dev/null +++ b/G/UTIL/GIFINTO.C @@ -0,0 +1,159 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to read stdin, and save it into the specified file iff the result * +* and inspired by the rle utah tool kit I decided to implement and add it. * +* -q : quite printing mode. * +* -s minsize : the minimum file size to keep it. * +* -h : on line help. * +****************************************************************************** +* History: * +* 7 Jul 89 - Version 1.0 by Gershon Elber. * +* 22 Dec 89 - Fix problem with tmpnam (Version 1.1). * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifInto" + +#define DEFAULT_MIN_FILE_SIZE 14 /* More than GIF stamp + screen desc. */ +#define DEFAULT_OUT_NAME "GifInto.Gif" +#define DEFAULT_TMP_NAME "TempInto.$$$" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifInto q%- s%-MinFileSize!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- s%-MinFileSize!d h%- GifFile!*s"; +#endif /* SYSV */ + +static int + MinFileSize = DEFAULT_MIN_FILE_SIZE; + +/****************************************************************************** +* The is simply: read until EOF, then close the output, test its length, and * +* if non zero then rename it. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, + MinSizeFlag = FALSE, HelpFlag = FALSE; + char **FileName = NULL, + TmpName[80], FoutTmpName[80], FullPath[80], DefaultName[80], s[80], *p; + FILE *Fin, *Fout; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &MinSizeFlag, &MinFileSize, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles != 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* Open the stdin in binary mode and increase its buffer size: */ +#ifdef __MSDOS__ + setmode(0, O_BINARY); /* Make sure it is in binary mode. */ + if ((Fin = fdopen(0, "rb")) == NULL || /* Make it into a stream: */ + setvbuf(Fin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE))/* Incr. stream buf.*/ +#else + if ((Fin = fdopen(0, "r")) == NULL) /* Make it into a stream: */ +#endif /* __MSDOS__ */ + GIF_EXIT("Failed to open input."); + + /* Isolate the directory where our destination is, and set tmp file name */ + /* in the very same directory. */ + strcpy(FullPath, *FileName); + if ((p = strrchr(FullPath, '/')) != NULL || + (p = strrchr(FullPath, '\\')) != NULL) + p[1] = 0; + else if ((p = strrchr(FullPath, ':')) != NULL) + p[1] = 0; + else + FullPath[0] = 0; /* No directory or disk specified. */ + + strcpy(FoutTmpName, FullPath); /* Generate destination temporary name. */ + /* Make sure the temporary is made in the current directory: */ + p = tmpnam(TmpName); + if (strrchr(p, '/')) p = strrchr(p, '/') + 1; + if (strrchr(p, '\\')) p = strrchr(p, '\\') + 1; + if (strlen(p) == 0) p = DEFAULT_TMP_NAME; + strcat(FoutTmpName, p); + +#ifdef __MSDOS__ + if ((Fout = fopen(FoutTmpName, "wb")) == NULL || + setvbuf(Fout, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE))/*Incr. stream buf.*/ +#else + if ((Fout = fopen(FoutTmpName, "w")) == NULL) +#endif /* __MSDOS__ */ + GIF_EXIT("Failed to open output."); + + while (!feof(Fin)) { + if (putc(getc(Fin), Fout) == EOF) + GIF_EXIT("Failed to write output."); + } + + fclose(Fin); + if (ftell(Fout) >= (long) MinFileSize) { + fclose(Fout); + unlink(*FileName); + if (rename(FoutTmpName, *FileName) != 0) { + strcpy(DefaultName, FullPath); + strcat(DefaultName, DEFAULT_OUT_NAME); + if (rename(FoutTmpName, DefaultName) == 0) { + sprintf(s, "Failed to rename out file - left as %s.", + DefaultName); + GIF_MESSAGE(s); + } + else { + unlink(FoutTmpName); + GIF_MESSAGE("Failed to rename out file - deleted."); + } + } + } + else { + fclose(Fout); + unlink(FoutTmpName); + GIF_MESSAGE("File too small - not renamed."); + } +} diff --git a/G/UTIL/GIFPOS.C b/G/UTIL/GIFPOS.C new file mode 100644 index 0000000..8f4841f --- /dev/null +++ b/G/UTIL/GIFPOS.C @@ -0,0 +1,202 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to reposition GIF file, by changing screen size and/or image(s) * +* position. Neither image(s) not colormap(s) are changed by any mean. * +* Options: * +* -q : quite printing mode. * +* -s w h : set new screen size - width & height. * +* -i t l : set new image position - top & left (for first image). * +* -n n w h : set new image position - top & left (for image number n). * +* -h : on line help. * +****************************************************************************** +* History: * +* 6 Jul 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifPos" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifPos q%- s%-Width|Height!d!d i%-Left|Top!d!d n%-n|Left|Top!d!d!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- s%-Width|Height!d!d i%-Left|Top!d!d n%-n|Left|Top!d!d!d h%- GifFile!*s"; +#endif /* SYSV */ + +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, ExtCode, CodeSize, ImageNum = 0, + ScreenFlag = FALSE, ScreenWidth, ScreenHeight, + ImageFlag = FALSE, ImageLeft, ImageTop, + ImageNFlag = FALSE, ImageN, ImageNLeft, ImageNTop, + HelpFlag = FALSE; + GifRecordType RecordType; + GifByteType *Extension, *CodeBlock; + char **FileName = NULL; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &ScreenFlag, &ScreenWidth, &ScreenHeight, + &ImageFlag, &ImageLeft, &ImageTop, + &ImageNFlag, &ImageN, &ImageNLeft, &ImageNTop, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* And dump out its new possible repositioned screen information: */ + if (EGifPutScreenDesc(GifFileOut, + ScreenFlag ? ScreenWidth : GifFileIn -> SWidth, + ScreenFlag ? ScreenHeight : GifFileIn -> SHeight, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + /* Put possibly repositioned image descriptor to out file: */ + if (++ImageNum == 1 && ImageFlag) { + /* First image should be repositioned: */ + if (EGifPutImageDesc(GifFileOut, + ImageLeft, ImageTop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + else if (ImageNum == ImageN && ImageNFlag) { + /* Image N should be repositioned: */ + if (EGifPutImageDesc(GifFileOut, + ImageNLeft, ImageNTop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* No repositioning for this image: */ + if (EGifPutImageDesc(GifFileOut, + GifFileIn -> ILeft, GifFileIn -> ITop, + GifFileIn -> IWidth, GifFileIn -> IHeight, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_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) == GIF_ERROR || + EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + while (CodeBlock != NULL) { + if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR || + EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_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); +} diff --git a/G/UTIL/GIFROTAT.C b/G/UTIL/GIFROTAT.C new file mode 100644 index 0000000..d130ca3 --- /dev/null +++ b/G/UTIL/GIFROTAT.C @@ -0,0 +1,322 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Aug. 1991 * +****************************************************************************** +* Program to rotate a GIF image by an arbitrary angle. * +* Options: * +* -q : quite printing mode. * +* -a Angle : angle to rotate with respect to the X axis. * +* -s Width Height : specifies size of output image. * +* -h : on line help. * +****************************************************************************** +* History: * +* 2 Aug 91 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif /* M_PI */ + +#define PROGRAM_NAME "GifRotat" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifRotat a!-Angle!d q%- s%-Width|Height!d!d h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " a!-Angle!d q%- s%-Width|Height!d!d h%- GifFile!*s"; +#endif /* SYSV */ + +static int + InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ + InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ + +static void RotateGifImage(GifRowType *ScreenBuffer, GifFileType *SrcGifFile, + int Angle, GifColorType *ColorMap, + int ExpColorMapSize, int DstWidth, int DstHeight); +static void RotateGifLine(GifRowType *ScreenBuffer, int BackGroundColor, + int SrcWidth, int SrcHeight, + int Angle, GifRowType DstLine, + int DstWidth, int DstHeight, int y); +static void QuitGifError(GifFileType *DstGifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Size, Error, NumFiles, Col, Row, Count, ExtCode, + ExpColorMapSize, DstWidth, DstHeight, Width, Height, + ImageNum = 0, + DstSizeFlag = FALSE, + AngleFlag = FALSE, + Angle = 0, + HelpFlag = FALSE; + char **FileName = NULL; + GifRecordType RecordType; + GifByteType *Extension; + GifFileType *GifFile; + GifRowType *ScreenBuffer; + GifColorType *ColorMap = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &AngleFlag, &Angle, &GifQuitePrint, + &DstSizeFlag, &DstWidth, &DstHeight, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Allocate the screen as vector of column of rows. We cannt allocate */ + /* the all screen at once, as this broken minded CPU can allocate up to */ + /* 64k at a time and our image can be bigger than that: */ + /* Note this screen is device independent - its the screen as defined by */ + /* the GIF file parameters itself. */ + if ((ScreenBuffer = (GifRowType *) + malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */ + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < GifFile -> SWidth; i++) /* Set its color to BackGround. */ + ScreenBuffer[0][i] = GifFile -> SBackGroundColor; + for (i = 1; i < GifFile -> SHeight; i++) { + /* Allocate the other rows, and set their color to background too: */ + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); + } + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + Row = GifFile -> ITop; /* Image Position relative to Screen. */ + Col = GifFile -> ILeft; + Width = GifFile -> IWidth; + Height = GifFile -> IHeight; + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height); + if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth || + GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) { + fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n"); + exit(-2); + } + if (GifFile -> IInterlace) { + /* Need to perform 4 passes on the images: */ + for (Count = i = 0; i < 4; i++) + for (j = Row + InterlacedOffset[i]; j < Row + Height; + j += InterlacedJumps[i]) { + GifQprintf("\b\b\b\b%-4d", Count++); + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], + Width) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType. */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap : + GifFile -> SColorMap); + ExpColorMapSize = GifFile -> IColorMap ? GifFile -> IBitsPerPixel : + GifFile -> SBitsPerPixel; + + if (!DstSizeFlag) { + DstWidth = GifFile -> SWidth; + DstHeight = GifFile -> SHeight; + } + + /* Perform the actual rotation and dump the image: */ + RotateGifImage(ScreenBuffer, GifFile, Angle, ColorMap, ExpColorMapSize, + DstWidth, DstHeight); +} + +/****************************************************************************** +* Save the GIF resulting image. * +******************************************************************************/ +static void RotateGifImage(GifRowType *ScreenBuffer, GifFileType *SrcGifFile, + int Angle, GifColorType *ColorMap, + int ExpColorMapSize, int DstWidth, int DstHeight) +{ + int i, + LineSize = DstWidth * sizeof(GifPixelType); + GifFileType *DstGifFile; + GifRowType LineBuffer; + + if ((LineBuffer = (GifRowType) malloc(LineSize)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + /* Open stdout for the output file: */ + if ((DstGifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(DstGifFile); + + if (EGifPutScreenDesc(DstGifFile, DstWidth, DstHeight, + ExpColorMapSize, 0, ExpColorMapSize, + ColorMap) == GIF_ERROR || + EGifPutImageDesc(DstGifFile, 0, 0, DstWidth, DstHeight, + FALSE, ExpColorMapSize, NULL) == GIF_ERROR) + QuitGifError(DstGifFile); + + for (i = 0; i < DstHeight; i++) { + RotateGifLine(ScreenBuffer, SrcGifFile -> SBackGroundColor, + SrcGifFile -> SWidth, SrcGifFile -> SHeight, + Angle, LineBuffer, DstWidth, DstHeight, i); + if (EGifPutLine(DstGifFile, LineBuffer, DstWidth) == GIF_ERROR) + QuitGifError(DstGifFile); + GifQprintf("\b\b\b\b%-4d", DstHeight - i - 1); + } + + if (EGifCloseFile(DstGifFile) == GIF_ERROR) + QuitGifError(DstGifFile); +} + + +/****************************************************************************** +* Save the GIF resulting image. * +******************************************************************************/ +static void RotateGifLine(GifRowType *ScreenBuffer, int BackGroundColor, + int SrcWidth, int SrcHeight, + int Angle, GifRowType DstLine, + int DstWidth, int DstHeight, int y) +{ + int x, + TransSrcX = SrcWidth / 2, + TransSrcY = SrcHeight / 2, + TransDstX = DstWidth / 2, + TransDstY = DstHeight / 2; + double SinAngle = sin(Angle * M_PI / 180.0), + CosAngle = cos(Angle * M_PI / 180.0); + + for (x = 0; x < DstWidth; x++) + { + int xc = x - TransDstX, + yc = y - TransDstY, + SrcX = xc * CosAngle - yc * SinAngle + TransSrcX, + SrcY = xc * SinAngle + yc * CosAngle + TransSrcY; + + if (SrcX < 0 || SrcX >= SrcWidth || + SrcY < 0 || SrcY >= SrcHeight) + { + /* Out of the source image domain - set it to background color. */ + *DstLine++ = BackGroundColor; + } + else + *DstLine++ = ScreenBuffer[SrcY][SrcX]; + } +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *DstGifFile) +{ + PrintGifError(); + if (DstGifFile != NULL) EGifCloseFile(DstGifFile); + exit(1); +} diff --git a/G/UTIL/GIFRSIZE.C b/G/UTIL/GIFRSIZE.C new file mode 100644 index 0000000..1f69070 --- /dev/null +++ b/G/UTIL/GIFRSIZE.C @@ -0,0 +1,306 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to resize GIF by given factors horizontally and vertically. * +* Options: * +* -q : quite printing mode. * +* -S x y : scale into size as specified by x and y. * +* -s r : resize both x & y direction by factor r. * +* -x r : resize the x direction (horizontally) by factor r. * +* -y r : resize the y direction (vertically) by factor r. * +* -h : on line help. * +****************************************************************************** +* History: * +* 4 Jul 89 - Version 1.0 by Gershon Elber. * +* 22 Dec 89 - Fix minor bag in discarding last line of input (Version 1.1). * +* 3 Aug 91 - make it scale by an arbitrary size value. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifRSize" + +#define MAX_SCALE 16.0 /* Maximum scaling factor. */ + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifRSize q%- S%-X|Y!d!d s%-Scale!F x%-XScale!F y%-YScale!F h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- S%-X|Y!d!d s%-Scale!F x%-XScale!F y%-YScale!F h%- GifFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static GifPixelType + BackGroundColor = 0; +static double + XScale = 0.5, + YScale = 0.5; +static int + XSize = 0, + YSize = 0; + +static void ResizeLine(GifRowType LineIn, GifRowType LineOut, + int InLineLen, int OutLineLen); +static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, iy, last_iy, l, t, w, h, Error, NumFiles, ExtCode, + ImageNum = 0, + SizeFlag = FALSE, + ScaleFlag = FALSE, + XScaleFlag = FALSE, + YScaleFlag = FALSE, + HelpFlag = FALSE; + double Scale, y; + GifRecordType RecordType; + char s[80]; + GifByteType *Extension; + GifRowType LineIn, LineOut; + char **FileName = NULL; + GifFileType *GifFileIn = NULL, *GifFileOut = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &SizeFlag, &XSize, &YSize, &ScaleFlag, &Scale, + &XScaleFlag, &XScale, &YScaleFlag, &YScale, + &HelpFlag, &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* If specific direction was set, set other direction to 1: */ + if (!XScaleFlag && YScaleFlag) XScale = 1.0; + if (!YScaleFlag && XScaleFlag) YScale = 1.0; + + /* If the specific direction was not set, but global one did use it: */ + if (!XScaleFlag && ScaleFlag) XScale = Scale; + if (!YScaleFlag && ScaleFlag) YScale = Scale; + + if (XScale > MAX_SCALE) { + sprintf(s, "XScale too big, maximum scale selected instead (%d).", + MAX_SCALE); + GIF_MESSAGE(s); + XScale = MAX_SCALE; + } + if (YScale > MAX_SCALE) { + sprintf(s, "YScale too big, maximum scale selected instead (%d).", + MAX_SCALE); + GIF_MESSAGE(s); + YScale = MAX_SCALE; + } + + if (NumFiles == 1) { + if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + else { + /* Use the stdin instead: */ + if ((GifFileIn = DGifOpenFileHandle(0)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + } + BackGroundColor = GifFileIn -> SBackGroundColor; + + /* If size was specified, it is used to derive the scale: */ + if (SizeFlag) { + XScale = XSize / ((double) GifFileIn -> SWidth); + YScale = YSize / ((double) GifFileIn -> SHeight); + } + else + { + XSize = (int) (GifFileIn -> SWidth * XScale + 0.5); + YSize = (int) (GifFileIn -> SHeight * YScale + 0.5); + } + + /* As at this time we know the Screen size of the input gif file, and as */ + /* all image(s) in file must be less/equal to it, we can allocate the */ + /* scan lines for the input file, and output file. The number of lines */ + /* to allocate for each is set by ScaleDown & XScale & YScale: */ + LineOut = (GifRowType) malloc(XSize * sizeof(GifPixelType)); + LineIn = (GifRowType) malloc(GifFileIn -> SWidth * sizeof(GifPixelType)); + + /* Open stdout for the output file: */ + if ((GifFileOut = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFileIn, GifFileOut); + + /* And dump out its new scaled screen information: */ + if (EGifPutScreenDesc(GifFileOut, XSize, YSize, + GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor, + GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* Scan the content of the GIF file and load the image(s) in: */ + do { + if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFileIn) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + /* Put the image descriptor to out file: */ + l = (int) (GifFileIn -> ILeft * XScale + 0.5); + w = (int) (GifFileIn -> IWidth * XScale + 0.5); + t = (int) (GifFileIn -> ITop * YScale + 0.5); + h = (int) (GifFileIn -> IHeight * YScale + 0.5); + if (l < 0) l = 0; + if (t < 0) t = 0; + if (l + w > XSize) w = XSize - l; + if (t + h > YSize) h = YSize - t; + + if (EGifPutImageDesc(GifFileOut, l, t, w, h, + GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel, + GifFileIn -> IColorMap) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + if (GifFileIn -> IInterlace) { + GIF_EXIT("Cannt resize interlaced images - use GifInter first."); + } + else { + GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, ++ImageNum, + GifFileOut -> ILeft, GifFileOut -> ITop, + GifFileOut -> IWidth, GifFileOut -> IHeight); + + for (i = GifFileIn -> IHeight, y = 0.0, last_iy = -1; + i-- > 0; + y += YScale) { + if (DGifGetLine(GifFileIn, LineIn, + GifFileIn -> IWidth) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + iy = (int) y; + if (last_iy < iy && last_iy < YSize) { + ResizeLine(LineIn, LineOut, + GifFileIn -> IWidth, GifFileOut -> IWidth); + + for (; + last_iy < iy && last_iy < GifFileOut -> IHeight - 1; + last_iy++) { + GifQprintf("\b\b\b\b%-4d", last_iy + 1); + if (EGifPutLine(GifFileOut, LineOut, + GifFileOut -> IWidth) == + GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + } + } + + /* If scale is not dividable - dump last lines: */ + while (++last_iy < GifFileOut -> IHeight) { + GifQprintf("\b\b\b\b%-4d", last_iy); + if (EGifPutLine(GifFileOut, LineOut, + GifFileOut -> IWidth) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + } + } + break; + case EXTENSION_RECORD_TYPE: + /* Skip any extension blocks in file: */ + if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifPutExtension(GifFileOut, ExtCode, Extension[0], + Extension) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + /* No support to more than one extension blocks, so discard: */ + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_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) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + if (EGifCloseFile(GifFileOut) == GIF_ERROR) + QuitGifError(GifFileIn, GifFileOut); + + free(LineOut); + free(LineIn); +} + +/****************************************************************************** +* Line resizing routine - scale given lines as follows: * +* Scale (by pixel duplication/elimination) from InLineLen to OutLineLen. * +******************************************************************************/ +static void ResizeLine(GifRowType LineIn, GifRowType LineOut, + int InLineLen, int OutLineLen) +{ + int i, ix, last_ix; + double x; + + OutLineLen--; + + for (i = InLineLen, x = 0.0, last_ix = -1; + i-- > 0; + x += XScale, LineIn++) + { + ix = (int) x; + for (; last_ix < ix && last_ix < OutLineLen; last_ix++) + *LineOut++ = *LineIn; + } + + /* Make sure the line is complete. */ + for (LineIn--; last_ix < OutLineLen; last_ix++) + *LineOut++ = *LineIn; +} + +/****************************************************************************** +* 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); +} diff --git a/G/UTIL/GIFTEXT.C b/G/UTIL/GIFTEXT.C new file mode 100644 index 0000000..eeee457 --- /dev/null +++ b/G/UTIL/GIFTEXT.C @@ -0,0 +1,459 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jun. 1989 * +****************************************************************************** +* Program to dump GIF file content as TEXT information * +* Options: * +* -q : quite printing mode. * +* -c : include the color maps as well. * +* -e : include encoded information packed as bytes as well. * +* -z : include encoded information (12bits) codes as result from the zl alg. * +* -p : dump pixel information instead of encoded information. * +* -r : same as -p but dump one pixel as one byte in binary form with no * +* other information. This will create a file of size Width by Height. * +* -h : on line help. * +****************************************************************************** +* History: * +* 28 Jun 89 - Version 1.0 by Gershon Elber. * +* 21 Dec 89 - Fix segmentation fault problem in PrintCodeBlock (Version 1.1) * +* 25 Dec 89 - Add the -r flag for raw output. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifText" + +#define MAKE_PRINTABLE(c) (isprint(c) ? (c) : ' ') + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifText q%- c%- e%- z%- p%- r%- h%- GifFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- c%- e%- z%- p%- r%- h%- GifFile!*s"; +#endif /* SYSV */ + +static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset); +static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset); +static void PrintExtBlock(GifByteType *Extension, int Reset); +static void PrintLZCodes(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, ExtCode, CodeSize, Error, NumFiles, Len, + ColorMapFlag = FALSE, EncodedFlag = FALSE, LZCodesFlag = FALSE, + PixelFlag = FALSE, HelpFlag = FALSE, RawFlag = FALSE, ImageNum = 1; + char *GifFileName, **FileName = NULL; + GifPixelType *Line; + GifRecordType RecordType; + GifByteType *CodeBlock, *Extension; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &ColorMapFlag, &EncodedFlag, + &LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (NumFiles == 1) { + GifFileName = *FileName; + if ((GifFile = DGifOpenFileName(*FileName)) == NULL) { + PrintGifError(); + exit(-1); + } + } + else { + /* Use the stdin instead: */ + GifFileName = "Stdin"; + if ((GifFile = DGifOpenFileHandle(0)) == NULL) { + PrintGifError(); + exit(-1); + } + } + + /* Because we write binary data - make sure no text will be written. */ + if (RawFlag) { + ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = FALSE; +#ifdef __MSDOS__ + setmode(1, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* __MSDOS__ */ + } + else { + printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n", + GifFileName, GifFile -> SWidth, GifFile -> SHeight); + printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d.\n", + GifFile -> SColorResolution, GifFile -> SBitsPerPixel, + GifFile -> SBackGroundColor); + if (GifFile -> SColorMap) + printf("\tHas Global Color Map.\n\n"); + else + printf("\tNo Global Color Map.\n\n"); + if (ColorMapFlag && GifFile -> SColorMap) { + printf("\tGlobal Color Map:\n"); + Len = 1 << GifFile -> SBitsPerPixel; + for (i = 0; i < Len; i+=4) { + for (j = 0; j < 4 && j < Len; j++) { + printf("%3d: %02xh %02xh %02xh ", i + j, + GifFile -> SColorMap[i + j].Red, + GifFile -> SColorMap[i + j].Green, + GifFile -> SColorMap[i + j].Blue); + } + printf("\n"); + } + } + } + + do { + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + switch (RecordType) { + case IMAGE_DESC_RECORD_TYPE: + if (DGifGetImageDesc(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + if (!RawFlag) { + printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n", + ImageNum++, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + printf("\tImage is %s", + GifFile -> IInterlace ? "Interlaced" : + "Non Interlaced"); + if (GifFile -> IColorMap != NULL) + printf(", BitsPerPixel = %d.\n", + GifFile -> IBitsPerPixel); + else + printf(".\n"); + if (GifFile -> IColorMap) + printf("\tImage Has Color Map.\n"); + else + printf("\tNo Image Color Map.\n"); + if (ColorMapFlag && GifFile -> IColorMap) { + Len = 1 << GifFile -> IBitsPerPixel; + for (i = 0; i < Len; i+=4) { + for (j = 0; j < 4 && j < Len; j++) { + printf("%3d: %02xh %02xh %02xh ", i + j, + GifFile -> IColorMap[i + j].Red, + GifFile -> IColorMap[i + j].Green, + GifFile -> IColorMap[i + j].Blue); + } + printf("\n"); + } + } + } + + if (EncodedFlag) { + if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + printf("\nImage LZ compressed Codes (Code Size = %d):\n", + CodeSize); + PrintCodeBlock(GifFile, CodeBlock, TRUE); + while (CodeBlock != NULL) { + if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + PrintCodeBlock(GifFile, CodeBlock, FALSE); + } + } + else if (LZCodesFlag) { + PrintLZCodes(GifFile); + } + else if (PixelFlag) { + Line = (GifPixelType *) malloc(GifFile -> IWidth * + sizeof(GifPixelType)); + for (i = 0; i < GifFile -> IHeight; i++) { + if (DGifGetLine(GifFile, Line, GifFile -> IWidth) + == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + PrintPixelBlock(Line, GifFile -> IWidth, i == 0); + } + PrintPixelBlock(NULL, GifFile -> IWidth, FALSE); + free((char *) Line); + } + else if (RawFlag) { + Line = (GifPixelType *) malloc(GifFile -> IWidth * + sizeof(GifPixelType)); + for (i = 0; i < GifFile -> IHeight; i++) { + if (DGifGetLine(GifFile, Line, GifFile -> IWidth) + == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + fwrite(Line, 1, GifFile -> IWidth, stdout); + } + free((char *) Line); + } + else { + /* Skip the image: */ + if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + while (CodeBlock != NULL) { + if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + } + + } + break; + case EXTENSION_RECORD_TYPE: + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + if (!RawFlag) { + printf("\nExtension Record (Ext Code = %d [%c]):\n", + ExtCode, MAKE_PRINTABLE(ExtCode)); + PrintExtBlock(Extension, TRUE); + } + while (Extension != NULL) { + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + PrintExtBlock(Extension, FALSE); + } + break; + case TERMINATE_RECORD_TYPE: + break; + default: /* Should be traps by DGifGetRecordType */ + break; + } + } + while (RecordType != TERMINATE_RECORD_TYPE); + + if (DGifCloseFile(GifFile) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + + if (!RawFlag) printf("\nGif file terminated normally.\n"); +} + +/****************************************************************************** +* Print the given CodeBlock - a string in pascal notation (size in first * +* place). Save local information so printing can be performed continuously, * +* or reset to start state if Reset. If CodeBlock is NULL, output is flushed * +******************************************************************************/ +static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset) +{ + static int CrntPlace = 0, Print = TRUE; + static long CodeCount = 0; + char c; + int i, Percent, Len; + long NumBytes; + + if (Reset || CodeBlock == NULL) { + if (CodeBlock == NULL) { + if (CrntPlace > 0) { + if (Print) printf("\n"); + CodeCount += CrntPlace - 16; + } + if (GifFile -> IColorMap) + NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight) + * GifFile -> IBitsPerPixel) / 8; + else + NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight) + * GifFile -> SBitsPerPixel) / 8; + Percent = 100 * CodeCount / NumBytes; + printf("\nCompression ratio: %ld/%ld (%d%%).\n", + CodeCount, NumBytes, Percent); + return; + } + CrntPlace = 0; + CodeCount = 0; + Print = TRUE; + } + + Len = CodeBlock[0]; + for (i = 1; i <= Len; i++) { + if (CrntPlace == 0) { + if (Print) printf("\n%05lxh: ", CodeCount); + CodeCount += 16; + } +#ifdef __MSDOS__ + if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE; +#endif /* __MSDOS__ */ + if (Print) printf(" %02xh", CodeBlock[i]); + if (++CrntPlace >= 16) CrntPlace = 0; + } +} + +/****************************************************************************** +* Print the given Extension - a string in pascal notation (size in first * +* place). Save local information so printing can be performed continuously, * +* or reset to start state if Reset. If Extension is NULL, output is flushed * +******************************************************************************/ +static void PrintExtBlock(GifByteType *Extension, int Reset) +{ + static int CrntPlace = 0, Print = TRUE; + static long ExtCount = 0; + static char HexForm[49], AsciiForm[17]; + char c; + int i, Len; + + if (Reset || Extension == NULL) { + if (Extension == NULL) { + if (CrntPlace > 0) { + HexForm[CrntPlace * 3] = 0; + AsciiForm[CrntPlace] = 0; + if (Print) printf("\n%05lx: %-49s %-17s\n", + ExtCount, HexForm, AsciiForm); + return; + } + else if (Print) + printf("\n"); + } + CrntPlace = 0; + ExtCount = 0; + Print = TRUE; + } + + if (!Print) return; + + Len = Extension[0]; + for (i = 1; i <= Len; i++) { + sprintf(&HexForm[CrntPlace * 3], " %02x", Extension[i]); + sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(Extension[i])); +#ifdef __MSDOS__ + if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE; +#endif /* __MSDOS__ */ + if (++CrntPlace == 16) { + HexForm[CrntPlace * 3] = 0; + AsciiForm[CrntPlace] = 0; + if (Print) printf("\n%05lx: %-49s %-17s", + ExtCount, HexForm, AsciiForm); + ExtCount += 16; + CrntPlace = 0; + } + } +} + +/****************************************************************************** +* Print the given PixelBlock of length Len. * +* Save local information so printing can be performed continuously, * +* or reset to start state if Reset. If PixelBlock is NULL, output is flushed * +******************************************************************************/ +static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset) +{ + static int CrntPlace = 0, Print = TRUE; + static long ExtCount = 0; + static char HexForm[49], AsciiForm[17]; + char c; + int i; + + if (Reset || PixelBlock == NULL) { + if (PixelBlock == NULL) { + if (CrntPlace > 0) { + HexForm[CrntPlace * 3] = 0; + AsciiForm[CrntPlace] = 0; + if (Print) printf("\n%05lx: %-49s %-17s\n", + ExtCount, HexForm, AsciiForm); + } + else if (Print) + printf("\n"); + } + CrntPlace = 0; + ExtCount = 0; + Print = TRUE; + if (PixelBlock == NULL) return; + } + + if (!Print) return; + + for (i = 0; i < Len; i++) { + sprintf(&HexForm[CrntPlace * 3], " %02x", PixelBlock[i]); + sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(PixelBlock[i])); +#ifdef __MSDOS__ + if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE; +#endif /* __MSDOS__ */ + if (++CrntPlace == 16) { + HexForm[CrntPlace * 3] = 0; + AsciiForm[CrntPlace] = 0; + if (Print) printf("\n%05lx: %-49s %-17s", + ExtCount, HexForm, AsciiForm); + ExtCount += 16; + CrntPlace = 0; + } + } +} + +/****************************************************************************** +* Print the image as LZ codes (each 12bits), until EOF marker is reached. * +******************************************************************************/ +static void PrintLZCodes(GifFileType *GifFile) +{ + char c; + int Code, Print = TRUE, CrntPlace = 0; + long CodeCount = 0; + + do { + if (Print && CrntPlace == 0) printf("\n%05lx:", CodeCount); + if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) { + PrintGifError(); + exit(-1); + } + if (Print && Code >= 0) + printf(" %03x", Code); /* EOF Code is returned as -1. */ + CodeCount++; + if (++CrntPlace >= 16) CrntPlace = 0; +#ifdef __MSDOS__ + if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE; +#endif /* __MSDOS__ */ + } + while (Code >= 0); +} diff --git a/G/UTIL/GIFWEDGE.C b/G/UTIL/GIFWEDGE.C new file mode 100644 index 0000000..e86a44e --- /dev/null +++ b/G/UTIL/GIFWEDGE.C @@ -0,0 +1,168 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to create a test image of White and Red/Green/Blue levels for * +* test purposes. The Primary (RGB) and Secondary (YCM) are also displayed. * +* background. * +* Options: * +* -q : quite printing mode. * +* -s Width Height : set image size. * +* -l levels : number of color levels. * +* -h : on line help. * +****************************************************************************** +* History: * +* 4 Jan 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "GifWedge" + +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 350 + +#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image. */ + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "GifWedge q%- l%-#Lvls!d s%-Width|Height!d!d h%-"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- l%-#Lvls!d s%-Width|Height!d!d h%-"; +#endif /* SYSV */ + +static int + NumLevels = DEFAULT_NUM_LEVELS, + ImageWidth = DEFAULT_WIDTH, + ImageHeight = DEFAULT_HEIGHT; + +static void QuitGifError(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, l, c, Error, LevelStep, LogNumLevels, + Count = 0, LevelsFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE; + GifRowType Line; + GifColorType *ColorMap; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &LevelsFlag, &NumLevels, + &SizeFlag, &ImageWidth, &ImageHeight, + &HelpFlag)) != FALSE) { + GAPrintErrMsg(Error); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + /* Make sure the number of levels is power of 2 (up to 32 levels.). */ + for (i = 1; i < 6; i++) if (NumLevels == (1 << i)) break; + if (i == 6) GIF_EXIT("#Lvls (-l option) is not power of 2 up to 32."); + LogNumLevels = i + 3; /* Multiple by 8 (see below). */ + LevelStep = 256 / NumLevels; + + /* Make sure the image dimension is a multiple of NumLevels horizontally */ + /* and 7 (White, Red, Green, Blue and Yellow Cyan Magenta) vertically. */ + ImageWidth = (ImageWidth / NumLevels) * NumLevels; + ImageHeight = (ImageHeight / 7) * 7; + + /* Open stdout for the output file: */ + if ((GifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFile); + + /* Dump out screen description with given size and generated color map: */ + /* The color map has 7 NumLevels colors for White, Red, Green and then */ + /* The secondary colors Yellow Cyan and magenta. */ + if ((ColorMap = (GifColorType *) + malloc(8 * NumLevels * sizeof(GifColorType))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < 8; i++) /* Set color map. */ + for (j = 0; j < NumLevels; j++) { + l = LevelStep * j; + c = i * NumLevels + j; + ColorMap[c].Red = (i == 0 || i == 1 || i == 4 || i == 6) * l; + ColorMap[c].Green = (i == 0 || i == 2 || i == 4 || i == 5) * l; + ColorMap[c].Blue = (i == 0 || i == 3 || i == 5 || i == 6) * l; + } + + if (EGifPutScreenDesc(GifFile, + ImageWidth, ImageHeight, LogNumLevels, 0, LogNumLevels, ColorMap) + == GIF_ERROR) + QuitGifError(GifFile); + + /* Dump out the image descriptor: */ + if (EGifPutImageDesc(GifFile, + 0, 0, ImageWidth, ImageHeight, FALSE, LogNumLevels, NULL) == GIF_ERROR) + QuitGifError(GifFile); + + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + /* Allocate one scan line to be used for all image. */ + if ((Line = (GifRowType) malloc(sizeof(GifPixelType) * ImageWidth)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + /* Dump the pixels: */ + for (c = 0; c < 7; c++) { + for (i = 0, l = 0; i < NumLevels; i++) + for (j = 0; j < ImageWidth / NumLevels; j++) + Line[l++] = i + NumLevels * c; + for (i = 0; i < ImageHeight / 7; i++) { + if (EGifPutLine(GifFile, Line, ImageWidth) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Count++); + } + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) + QuitGifError(GifFile); +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFile) +{ + PrintGifError(); + if (GifFile != NULL) DGifCloseFile(GifFile); + exit(1); +} diff --git a/G/UTIL/GIF_LIB.H b/G/UTIL/GIF_LIB.H new file mode 100644 index 0000000..d4b9834 --- /dev/null +++ b/G/UTIL/GIF_LIB.H @@ -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 */ diff --git a/G/UTIL/HERC2GIF.C b/G/UTIL/HERC2GIF.C new file mode 100644 index 0000000..93c6ee3 --- /dev/null +++ b/G/UTIL/HERC2GIF.C @@ -0,0 +1,26 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jun. 1989 * +****************************************************************************** +* Program to dump the hercules graphic screen into a GIF file * +****************************************************************************** +* History: * +* 26 Jun 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#include +#include "gif_lib.h" + +#define DEFAULT_NAME "hercules.gif" + +/****************************************************************************** +* Simple - isnt it? * +******************************************************************************/ +void main(int argc, char **argv) +{ + if (argc == 2) + DumpScreen2Gif(argv[1], HERCMONO, HERCMONOHI, 0, 0); + else + DumpScreen2Gif(DEFAULT_NAME, HERCMONO, HERCMONOHI, 0, 0); +} diff --git a/G/UTIL/M.BAT b/G/UTIL/M.BAT new file mode 100644 index 0000000..77dea68 --- /dev/null +++ b/G/UTIL/M.BAT @@ -0,0 +1 @@ +make -fmakefile.tc \ No newline at end of file diff --git a/G/UTIL/MAKDEBUG.TC b/G/UTIL/MAKDEBUG.TC new file mode 100644 index 0000000..0741f50 --- /dev/null +++ b/G/UTIL/MAKDEBUG.TC @@ -0,0 +1,72 @@ +# +# This is the make file for the util subdirectory of the GIF library +# In order to run it tcc is assumed to be available, in addition to +# tlib and 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. +# +# +# This make file requires: +# 1. Setting the TC libraries directory as CC_LIBS below. Make sure this +# is really short (because of DOS stupid limit on command line length). +# 2. Setting the executables destination directory as DEST below. Make +# sure that directory do exists. +# 2. Making new library named graphbgi.lib holds the drivers for the different +# devices (using bgiobj.exe and tlib.exe utilities). +# +# Gershon Elber, Jun 1989 +# + + +# Works only on TC++ 1.0 make - swap out make before invoking command. +.SWAP + +# Your C compiler +CC = bcc + +# MDL set? +!if !$d(MDL) +MDL=l +!endif + +# Where all the include files are: +INC = ..\lib +GIF_INC = $(INC)\gif_lib.h $(INC)\getarg.h + +# And libararies: +GIF_LIB = ..\lib\gif_lib$(MDL).lib +CC_LIBS = ..\lib\\ +LIBS = $(GIF_LIB) $(CC_LIBS)graphics.lib $(CC_LIBS)graphbgi.lib \ + $(CC_LIBS)emu.lib $(CC_LIBS)math$(MDL).lib + +# Note the tcc xxxxxx.tc files enables ALL warnings for more strict tests so +# you should use them during debuging. I didnt add it here as command lines +# are limited to 128 chars... +# +# Optimized version: +CFLAGS = -m$(MDL) -a- -f -G -O -r -c -d -w -v- -y- -k- -M- +#CFLAGS = ml -a- -f -G -O- -r -c -d -w -v- -y- -k- -M- +# +# Debugging version: +# CFLAGS = -m$(MDL) -a- -f -c -d -w -v -y -k -M- +# LFLAGS = -lvlc + +ALL = gifdebug.exe + +all: $(ALL) + +# +# Note we go all the way to the exe file using this rule. +# +# LZEXE is an EXE compressor program. If you dont have it remove the two +# lines of 'lzexe $&.exe' and 'del $&.old'. +# +.c.obj: + $(CC) -I$(INC) $(CFLAGS) $&.c + $(CC) -m$(MDL) $(LFLAGS) $&.obj $(LIBS) + del gifdebug.exe + ren gifhn.exe gifdebug.exe + +gifdebug.exe: gifhn.obj +gifhn.obj: $(GIF_INC) diff --git a/G/UTIL/MAKEFILE.TC b/G/UTIL/MAKEFILE.TC new file mode 100644 index 0000000..b775ec1 --- /dev/null +++ b/G/UTIL/MAKEFILE.TC @@ -0,0 +1,158 @@ +# +# This is the make file for the util subdirectory of the GIF library +# In order to run it tcc is assumed to be available, in addition to +# tlib and 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. +# +# +# This make file requires: +# 1. Setting the TC libraries directory as CC_LIBS below. Make sure this +# is really short (because of DOS stupid limit on command line length). +# 2. Setting the executables destination directory as DEST below. Make +# sure that directory do exists. +# 2. Making new library named graphbgi.lib holds the drivers for the different +# devices (using bgiobj.exe and tlib.exe utilities). +# +# Gershon Elber, Jun 1989 +# + + +# Works only on TC++ 1.0 make and up - swap out make before invoking command. +.SWAP + +# Your C compiler +CC = bcc + +# MDL set? +!if !$d(MDL) +MDL=l +!endif + +# Where all the include files are: +##################################################################### +##################################################################### +INC = E:\ +##################################################################### +##################################################################### +GIF_INC = e:\gif_lib.h e:\getarg.h +# $(INC)\gif_lib.h $(INC)\getarg.h + +# And libararies: +GIF_LIB = e:\gif_lib$(MDL).lib +CC_LIBS = e:\ +BGI_LIB = e:\graphbgi.lib +LIBS = $(GIF_LIB) $(CC_LIBS)graphics.lib $(BGI_LIB) \ + $(CC_LIBS)emu.lib $(CC_LIBS)math$(MDL).lib + +# Where to copy executables to: +DEST = ..\gif + +# Note the tcc xxxxxx.tc files enables ALL warnings for more strict tests so +# you should use them during debuging. I didnt add it here as command lines +# are limited to 128 chars... +# +# Optimized version: +CFLAGS = -m$(MDL) -a- -f -G -O -r -c -d -w -v- -y- -k- -M- +# +# Debugging version: +# CFLAGS = -m$(MDL) -a- -f -c -d -w -v -y -k -M- +# LFLAGS = -lvlc + +ALL = $(DEST)\gif2bgi.exe $(DEST)\gif2epsn.exe $(DEST)\gif2herc.exe \ + $(DEST)\gif2ps.exe $(DEST)\gif2rgb.exe $(DEST)\gifasm.exe \ + $(DEST)\gifbg.exe $(DEST)\gifclip.exe $(DEST)\gifclrmp.exe \ + $(DEST)\gifcomb.exe $(DEST)\giffix.exe $(DEST)\gifflip.exe \ + $(DEST)\gifhisto.exe $(DEST)\gifinter.exe $(DEST)\gifinto.exe \ + $(DEST)\gifpos.exe $(DEST)\gifrotat.exe $(DEST)\gifrsize.exe \ + $(DEST)\giftext.exe $(DEST)\gifwedge.exe $(DEST)\herc2gif.exe \ + $(DEST)\raw2gif.exe $(DEST)\rgb2gif.exe $(DEST)\text2gif.exe + +allexe: $(ALL) + +# +# Note we go all the way to the exe file using this rule. +# +# LZEXE is an EXE compressor program. If you dont have it remove the two +# lines of 'lzexe $&.exe' and 'del $&.old'. +# +.c.obj: + $(CC) $(CFLAGS) -I$(INC) $&.c + $(CC) -m$(MDL) $(LFLAGS) $&.obj $(LIBS) +# lzexe $&.exe +# del $&.old +# copy $&.exe $(DEST) +# del $&.exe + +$(DEST)\gif2bgi.exe: gif2bgi.obj +gif2bgi.obj: $(GIF_INC) + +$(DEST)\gif2epsn.exe: gif2epsn.obj +gif2epsn.obj: $(GIF_INC) + +$(DEST)\gif2herc.exe: gif2herc.obj $(GIF_LIB) +gif2herc.obj: $(GIF_INC) + +$(DEST)\gif2ps.exe: gif2ps.obj $(GIF_LIB) +gif2ps.obj: $(GIF_INC) + +$(DEST)\gif2rgb.exe: gif2rgb.obj $(GIF_LIB) +gif2rgb.obj: $(GIF_INC) + +$(DEST)\gifasm.exe: gifasm.obj $(GIF_LIB) +gifasm.obj: $(GIF_INC) + +$(DEST)\gifbg.exe: gifbg.obj $(GIF_LIB) +gifbg.obj: $(GIF_INC) + +$(DEST)\gifclip.exe: gifclip.obj $(GIF_LIB) +gifclip.obj: $(GIF_INC) + +$(DEST)\gifclrmp.exe: gifclrmp.c gifclrmp.obj $(GIF_LIB) +gifclrmp.obj: $(GIF_INC) + +$(DEST)\gifcomb.exe: gifcomb.obj $(GIF_LIB) +gifcomb.obj: $(GIF_INC) + +$(DEST)\giffix.exe: giffix.obj $(GIF_LIB) +giffix.obj: $(GIF_INC) + +$(DEST)\gifflip.exe: gifflip.obj $(GIF_LIB) +gifflip.obj: $(GIF_INC) + +$(DEST)\gifhisto.exe: gifhisto.obj $(GIF_LIB) +gifhisto.obj: $(GIF_INC) + +$(DEST)\gifinter.exe: gifinter.obj $(GIF_LIB) +gifinter.obj: $(GIF_INC) + +$(DEST)\gifinto.exe: gifinto.obj $(GIF_LIB) +gifinto.obj: $(GIF_INC) + +$(DEST)\gifpos.exe: gifpos.obj $(GIF_LIB) +gifpos.obj: $(GIF_INC) + +$(DEST)\gifrotat.exe: gifrotat.obj $(GIF_LIB) +gifrotat.obj: $(GIF_INC) + +$(DEST)\gifrsize.exe: gifrsize.obj $(GIF_LIB) +gifrsize.obj: $(GIF_INC) + +$(DEST)\giftext.exe: giftext.obj $(GIF_LIB) +giftext.obj: $(GIF_INC) + +$(DEST)\gifwedge.exe: gifwedge.obj $(GIF_LIB) +gifwedge.obj: $(GIF_INC) + +$(DEST)\herc2gif.exe: herc2gif.obj $(GIF_LIB) +herc2gif.obj: $(GIF_INC) + +$(DEST)\raw2gif.exe: raw2gif.obj $(GIF_LIB) +raw2gif.obj: $(GIF_INC) + +$(DEST)\rgb2gif.exe: rgb2gif.obj $(GIF_LIB) +rgb2gif.obj: $(GIF_INC) + +$(DEST)\text2gif.exe: text2gif.obj $(GIF_LIB) +text2gif.obj: $(GIF_INC) diff --git a/G/UTIL/MAKEFILE.UNX b/G/UTIL/MAKEFILE.UNX new file mode 100644 index 0000000..2f7732c --- /dev/null +++ b/G/UTIL/MAKEFILE.UNX @@ -0,0 +1,189 @@ +# +# This is the make file for the util subdirectory of the GIF library +# In order to run it gcc is assumed to be available (gnu c compiler) +# You may try other c compilers but the must support ansi c! +# +# Usage: "make -f makefile.unx [all] [rle] [iris] +# +# This make file is for Unix BSD type of machines. +# +# Gershon Elber, Dec 1989 +# + +# +# If you have the utah raster tool kit and wants conversion routines to and +# from it set the ones below properly. +# +RLE_INC = -I/u/urt/urt3.0/include +RLE_LIB = /u/urt/urt3.0/lib/librle.a +X_LIB_DIR = /server/sun4/usr/new/lib/X11R4 + +# Where are all the include files and libraryies for the gif utils: +INC = -I../lib +GIF_LIB = ../lib/libgif.a +GIF_LIB_DEPEND = ../lib/libgif.a ../lib/gif_lib.h ../lib/getarg.h + +# Where to copy executables to: +DEST = ../bin + +# +# These are the flags for gcc, in BSD4.3 or Sun O.S. 4.0.3 +# +# If your system has all function prototypes for gcc, replace all +# the -Wxxx with -Wall. I can not add -Wimplicit as my system uses old cc +# h files. +# +# +# CC = gcc +# +# CFLAGS = -O -c -W -Wreturn-type -Wcomment +# CFLAGS = -g -pg -c -W -Wreturn-type -Wcomment +# +# for sun 4 (gunnars@ifi.uib.no). Tested using gcc 1.39. +# +# CFLAGS = -O -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS +# CFLAGS = -g -c -sun4 -W -Wreturn-type -Wcomment -DUSE_VARARGS +# +# MORELIBS = + +# +# These are the flags for cc on SGI iris4d. O.S. IRIX 3.2. Note you must +# Define MORELIBS as well. +# +CC = cc +# +CFLAGS = -O -c -DSYSV -DNO_VOID_PTR -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4 +# CFLAGS = -g -p -c -DSYSV -DNO_VOID_PTR -Olimit 1000 -Wf,-XNh5000 -Wf,-XNd5000 -G 4 +# MORELIBS = -lbsd + +# +# These are the flags for xlc, ansi compiler for IBM R6000 +# +# CC = xlc +# +# CFLAGS = -O -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000 +# CFLAGS = -g -pg -c -qnoro -D_POSIX_SOURCE -D_ALL_SOURCE -DR6000 +# MORELIBS = + + +ALL = $(DEST)/gif2epsn $(DEST)/gif2ps $(DEST)/gif2rgb \ + $(DEST)/gif2x11 $(DEST)/gifasm $(DEST)/gifbg \ + $(DEST)/gifclip $(DEST)/gifclrmp $(DEST)/gifcomb \ + $(DEST)/giffix $(DEST)/gifflip $(DEST)/gifhisto \ + $(DEST)/gifinter $(DEST)/gifinto $(DEST)/gifpos \ + $(DEST)/gifrotat $(DEST)/gifrsize $(DEST)/giftext \ + $(DEST)/gifwedge $(DEST)/raw2gif $(DEST)/rgb2gif \ + $(DEST)/text2gif + +RLE = $(DEST)/gif2rle $(DEST)/rle2gif + +IRIS = $(DEST)/gif2iris + +.c.o: + $(CC) $(CFLAGS) $(INC) $(RLE_INC) $< + +all: $(ALL) +rle: $(RLE) +iris: $(IRIS) + +$(DEST)/gif2epsn: gif2epsn.o $(GIF_LIB_DEPEND) + $(CC) gif2epsn.o -o gif2epsn $(GIF_LIB) + mv -f gif2epsn $(DEST) + +$(DEST)/gif2iris: gif2iris.o $(GIF_LIB_DEPEND) + $(CC) gif2iris.o -o gif2iris $(GIF_LIB) -lgl_s + mv -f gif2iris $(DEST) + +$(DEST)/gif2ps: gif2ps.o $(GIF_LIB_DEPEND) + $(CC) gif2ps.o -o gif2ps $(GIF_LIB) + mv -f gif2ps $(DEST) + +$(DEST)/gif2rgb: gif2rgb.o $(GIF_LIB_DEPEND) + $(CC) gif2rgb.o -o gif2rgb $(GIF_LIB) + mv -f gif2rgb $(DEST) + +$(DEST)/gif2x11: gif2x11.o $(GIF_LIB_DEPEND) + $(CC) gif2x11.o -o gif2x11 $(GIF_LIB) -L$(X_LIB_DIR) -lX11 $(MORELIBS) + mv -f gif2x11 $(DEST) + +$(DEST)/gifasm: gifasm.o $(GIF_LIB_DEPEND) + $(CC) gifasm.o -o gifasm $(GIF_LIB) + mv -f gifasm $(DEST) + +$(DEST)/gifbg: gifbg.o $(GIF_LIB_DEPEND) + $(CC) gifbg.o -o gifbg $(GIF_LIB) + mv -f gifbg $(DEST) + +$(DEST)/gifclip: gifclip.o $(GIF_LIB_DEPEND) + $(CC) gifclip.o -o gifclip $(GIF_LIB) + mv -f gifclip $(DEST) + +$(DEST)/gifclrmp: gifclrmp.o $(GIF_LIB_DEPEND) + $(CC) gifclrmp.o -o gifclrmp $(GIF_LIB) -lm + mv -f gifclrmp $(DEST) + +$(DEST)/gifcomb: gifcomb.o $(GIF_LIB_DEPEND) + $(CC) gifcomb.o -o gifcomb $(GIF_LIB) + mv -f gifcomb $(DEST) + +$(DEST)/giffix: giffix.o $(GIF_LIB_DEPEND) + $(CC) giffix.o -o giffix $(GIF_LIB) + mv -f giffix $(DEST) + +$(DEST)/gifflip: gifflip.o $(GIF_LIB_DEPEND) + $(CC) gifflip.o -o gifflip $(GIF_LIB) + mv -f gifflip $(DEST) + +$(DEST)/gifhisto: gifhisto.o $(GIF_LIB_DEPEND) + $(CC) gifhisto.o -o gifhisto $(GIF_LIB) + mv -f gifhisto $(DEST) + +$(DEST)/gifinter: gifinter.o $(GIF_LIB_DEPEND) + $(CC) gifinter.o -o gifinter $(GIF_LIB) + mv -f gifinter $(DEST) + +$(DEST)/gifinto: gifinto.o $(GIF_LIB_DEPEND) + $(CC) gifinto.o -o gifinto $(GIF_LIB) + mv -f gifinto $(DEST) + +$(DEST)/gifpos: gifpos.o $(GIF_LIB_DEPEND) + $(CC) gifpos.o -o gifpos $(GIF_LIB) + mv -f gifpos $(DEST) + +$(DEST)/gifrotat: gifrotat.o $(GIF_LIB_DEPEND) + $(CC) gifrotat.o -o gifrotat $(GIF_LIB) -lm + mv -f gifrotat $(DEST) + +$(DEST)/gifrsize: gifrsize.o $(GIF_LIB_DEPEND) + $(CC) gifrsize.o -o gifrsize $(GIF_LIB) + mv -f gifrsize $(DEST) + +$(DEST)/giftext: giftext.o $(GIF_LIB_DEPEND) + $(CC) giftext.o -o giftext $(GIF_LIB) + mv -f giftext $(DEST) + +$(DEST)/gifwedge: gifwedge.o $(GIF_LIB_DEPEND) + $(CC) gifwedge.o -o gifwedge $(GIF_LIB) + mv -f gifwedge $(DEST) + +$(DEST)/raw2gif: raw2gif.o $(GIF_LIB_DEPEND) + $(CC) raw2gif.o -o raw2gif $(GIF_LIB) + mv -f raw2gif $(DEST) + +$(DEST)/text2gif: text2gif.o $(GIF_LIB_DEPEND) + $(CC) text2gif.o -o text2gif $(GIF_LIB) + mv -f text2gif $(DEST) + +$(DEST)/rgb2gif: rgb2gif.o $(GIF_LIB_DEPEND) + $(CC) rgb2gif.o -o rgb2gif $(GIF_LIB) + mv -f rgb2gif $(DEST) + +# +# The utah raster toolkit conversion routines: +# +$(DEST)/gif2rle: gif2rle.o $(GIF_LIB_DEPEND) + $(CC) gif2rle.o -o gif2rle $(GIF_LIB) $(RLE_LIB) + mv -f gif2rle $(DEST) +$(DEST)/rle2gif: rle2gif.o $(GIF_LIB_DEPEND) + $(CC) rle2gif.o -o rle2gif $(GIF_LIB) $(RLE_LIB) + mv -f rle2gif $(DEST) diff --git a/G/UTIL/RAW2GIF.C b/G/UTIL/RAW2GIF.C new file mode 100644 index 0000000..8968939 --- /dev/null +++ b/G/UTIL/RAW2GIF.C @@ -0,0 +1,254 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jun. 1989 * +****************************************************************************** +* Module to conver raw image into a GIF file. * +* Options: * +* -q : quite printing mode. * +* -s Width Height : specifies size of raw image. * +* -p ColorMapFile : specifies color map for ray image (see gifclrmp). * +* -h : on line help. * +****************************************************************************** +* History: * +* 15 Oct 89 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "getarg.h" +#include "gif_lib.h" + +#define PROGRAM_NAME "Raw2Gif" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Raw2Gif q%- s!-Width|Height!d!d p%-ColorMapFile!s h%- RawFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- s!-Width|Height!d!d p%-ColorMapFile!s h%- RawFile!*s"; +#endif /* SYSV */ + +static GifColorType EGAPallete[] = /* Default color map is EGA pallete. */ +{ + { 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 */ +}; +#define EGA_PALLETE_SIZE (sizeof(EGAPallete) / sizeof(GifColorType)) + +int Raw2Gif(int ImagwWidth, int ImagwHeight, + GifColorType *ColorMap, int ColorMapSize); +static int HandleGifError(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line, prepar global data and call the Gif routines. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, ImageWidth, ImageHeight, Dummy, Red, Green, Blue, + ColorMapSize, InFileHandle, + ImageSizeFlag = FALSE, ColorMapFlag = FALSE, HelpFlag = FALSE; + char **FileName = NULL, *ColorMapFile; + GifColorType *ColorMap; + FILE *InColorMapFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &ImageSizeFlag, &ImageWidth, &ImageHeight, + &ColorMapFlag, &ColorMapFile, + &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (ColorMapFlag) { + /* Read color map from given file: */ + if ((InColorMapFile = fopen(ColorMapFile, "rt")) == NULL) { + GIF_MESSAGE("Failed to open COLOR MAP file (not exists!?)."); + exit(2); + } + if ((ColorMap = (GifColorType *) + malloc(sizeof(GifColorType) * 255)) /* Biggest map. */ + == NULL) { + GIF_MESSAGE("Failed to allocate bitmap, aborted."); + exit(3); + } + + for (ColorMapSize = 0; + ColorMapSize < 256 && !feof(InColorMapFile); + ColorMapSize++) { + fscanf(InColorMapFile, "%3d %3d %3d %3d\n", + &Dummy, &Red, &Green, &Blue); + ColorMap[ColorMapSize].Red = Red; + ColorMap[ColorMapSize].Green = Green; + ColorMap[ColorMapSize].Blue = Blue; + } + } + else { + ColorMap = EGAPallete; + ColorMapSize = EGA_PALLETE_SIZE; + } + + if (NumFiles == 1) { +#ifdef __MSDOS__ + if ((InFileHandle = open(*FileName, O_RDONLY | O_BINARY)) == -1) { +#else + if ((InFileHandle = open(*FileName, O_RDONLY)) == -1) { +#endif /* __MSDOS__ */ + GIF_MESSAGE("Failed to open RAW image file (not exists!?)."); + exit(2); + } + dup2(InFileHandle, 0); /* Make stdin from this file. */ + } + else { +#ifdef __MSDOS__ + setmode(0, O_BINARY); /* Make sure it is in binary mode. */ +#endif /* __MSDOS__ */ + } + +#ifdef __MSDOS__ + setvbuf(stdin, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); +#endif /* __MSDOS__ */ + + /* Conver Raw image from stdin to Gif file in stdout: */ + Raw2Gif(ImageWidth, ImageHeight, ColorMap, ColorMapSize); +} + +/****************************************************************************** +* Convert Raw image (One byte per pixel) into Gif file. Raw data is read from * +* stdin, and Gif is dumped to stdout. ImagwWidth times ImageHeight bytes are * +* read. Color map is dumped from ColorMap. * +******************************************************************************/ +int Raw2Gif(int ImageWidth, int ImageHeight, + GifColorType *ColorMap, int ColorMapSize) +{ + static int BitsPerPixelArray[] = { 2, 4 ,8, 16, 32, 64, 128, 256 }; + int i, j, BitsPerPixel; + static GifPixelType *ScanLine; + GifFileType *GifFile; + + for (BitsPerPixel = 0; + BitsPerPixel < 8 && BitsPerPixelArray[BitsPerPixel] != ColorMapSize; + BitsPerPixel++); + if (++BitsPerPixel > 8) { + GIF_MESSAGE("Number of color map is NOT power of 2 up to 256."); + exit(3); + } + + if ((ScanLine = (GifPixelType *) malloc(sizeof(GifPixelType) * ImageWidth)) + == NULL) { + GIF_MESSAGE("Failed to allocate scan line, aborted."); + exit(3); + } + + if ((GifFile = EGifOpenFileHandle(1)) == NULL) { /* Gif to stdout. */ + free((char *) ScanLine); + return HandleGifError(GifFile); + } + + if (EGifPutScreenDesc(GifFile, ImageWidth, ImageHeight, BitsPerPixel, + 0, BitsPerPixel, ColorMap) == GIF_ERROR) { + free((char *) ScanLine); + return HandleGifError(GifFile); + } + + if (EGifPutImageDesc(GifFile, 0, 0, ImageWidth, ImageHeight, FALSE, 1, + NULL) == GIF_ERROR) { + free((char *) ScanLine); + return HandleGifError(GifFile); + } + + /* Here it is - get one raw line from stdin, and dump to stdout Gif: */ + GifQprintf("\n%s: Image 1 at (0, 0) [%dx%d]: ", + PROGRAM_NAME, ImageWidth, ImageHeight); + for (i = 0; i < ImageHeight; i++) { + /* Note we assume here PixelSize == Byte, which is not necessarily */ + /* so. If not - must read one byte at a time, and coerce to pixel. */ + if (fread(ScanLine, 1, ImageWidth, stdin) != ImageWidth) { + GIF_MESSAGE("RAW input file ended prematurely."); + exit(3); + } + + for (j = 0; j < ImageWidth; j++) + if (ScanLine[j] >= ColorMapSize) + GIF_MESSAGE("Warning: RAW data color > maximum color map entry."); + + if (EGifPutLine(GifFile, ScanLine, ImageWidth) == GIF_ERROR) { + free((char *) ScanLine); + return HandleGifError(GifFile); + } + GifQprintf("\b\b\b\b%-4d", i); + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) { + free((char *) ScanLine); + return HandleGifError(GifFile); + } + + free((char *) ScanLine); + return 0; +} + +/****************************************************************************** +* 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; +} diff --git a/G/UTIL/RGB2GIF.C b/G/UTIL/RGB2GIF.C new file mode 100644 index 0000000..f080aea --- /dev/null +++ b/G/UTIL/RGB2GIF.C @@ -0,0 +1,292 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jun. 1991 * +****************************************************************************** +* Program to convert 24bits RGB files to GIF format. * +* Options: * +* -q : quite printing mode. * +* -c #colors : in power of two, i.e. 7 will allow upto 128 colors in output. * +* -1 : one file holding RGBRGB.. triples of bytes * +* -s Width Height : specifies size of raw image. * +* -h : on line help. * +****************************************************************************** +* History: * +* 15 Jun 91 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "RGB2Gif" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "RGB2Gif q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- RGBFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- RGBFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ColorFlag = FALSE, + ExpNumOfColors = 8, + OneFileFlag = FALSE, + HelpFlag = FALSE, + ColorMapSize = 256; + +static void LoadRGB(char *FileName, + int OneFileFlag, + GifByteType **RedBuffer, + GifByteType **GreenBuffer, + GifByteType **BlueBuffer, + int Width, int Height); +static void SaveGif(GifByteType *OutputBuffer, + GifColorType *OutputColorMap, + int ExpColorMapSize, int Width, int Height); +static void QuitGifError(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int Error, NumFiles, Width, Height, SizeFlag; + char **FileName = NULL; + GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL, + *OutputBuffer = NULL; + GifColorType *OutputColorMap = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &ColorFlag, &ExpNumOfColors, &OneFileFlag, + &SizeFlag, &Width, &Height, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + ColorMapSize = 1 << ExpNumOfColors; + + if (NumFiles == 1) { + LoadRGB(*FileName, OneFileFlag, + &RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height); + } + else { + LoadRGB(NULL, OneFileFlag, + &RedBuffer, &GreenBuffer, &BlueBuffer, Width, Height); + } + + if ((OutputColorMap = (GifColorType *) malloc(ColorMapSize * + sizeof(GifColorType))) == NULL || + (OutputBuffer = (GifByteType *) malloc(Width * Height * + sizeof(GifByteType))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + if (QuantizeBuffer(Width, Height, &ColorMapSize, + RedBuffer, GreenBuffer, BlueBuffer, + OutputBuffer, OutputColorMap) == GIF_ERROR) + QuitGifError(NULL); + free((char *) RedBuffer); + free((char *) GreenBuffer); + free((char *) BlueBuffer); + + SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height); +} + +/****************************************************************************** +* Load RGB file into internal frame buffer. * +******************************************************************************/ +static void LoadRGB(char *FileName, + int OneFileFlag, + GifByteType **RedBuffer, + GifByteType **GreenBuffer, + GifByteType **BlueBuffer, + int Width, int Height) +{ + int i, j; + unsigned long Size; + GifByteType *RedP, *GreenP, *BlueP; + FILE *f[3]; + + Size = ((long) Width) * Height * sizeof(GifByteType); +#ifdef __MSDOS__ + if (Size > 65500L) + GIF_EXIT("Can't allocate more than 64k."); +#endif /* __MSDOS__ */ + + if ((*RedBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL || + (*GreenBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL || + (*BlueBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + RedP = *RedBuffer; + GreenP = *GreenBuffer; + BlueP = *BlueBuffer; + + if (FileName != NULL) { + char OneFileName[80]; + + if (OneFileFlag) { +#ifdef __MSDOS__ + if ((f[0] = fopen(FileName, "rb")) == NULL) +#else + if ((f[0] = fopen(FileName, "r")) == NULL) +#endif /* __MSDOS__ */ + GIF_EXIT("Can't open input file name."); + } + else { + static char *Postfixes[] = { ".R", ".G", ".B" }; + + for (i = 0; i < 3; i++) { + strcpy(OneFileName, FileName); + strcat(OneFileName, Postfixes[i]); + +#ifdef __MSDOS__ + if ((f[i] = fopen(OneFileName, "rb")) == NULL) +#else + if ((f[i] = fopen(OneFileName, "r")) == NULL) +#endif /* __MSDOS__ */ + GIF_EXIT("Can't open input file name."); + } + } + } + else { + OneFileFlag = TRUE; + +#ifdef __MSDOS__ + setmode(0, O_BINARY); +#endif /* __MSDOS__ */ + + f[0] = stdin; + } + + GifQprintf("\n%s: RGB image: ", PROGRAM_NAME); + + if (OneFileFlag) { + GifByteType *Buffer, *BufferP; + + if ((Buffer = (GifByteType *) malloc(Width * 3)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (fread(Buffer, Width * 3, 1, f[0]) != 1) + GIF_EXIT("Input file(s) terminated prematurly."); + for (j = 0, BufferP = Buffer; j < Width; j++) { + *RedP++ = *BufferP++; + *GreenP++ = *BufferP++; + *BlueP++ = *BufferP++; + } + } + + free((char *) Buffer); + fclose(f[0]); + } + else { + for (i = 0; i < Height; i++) { + GifQprintf("\b\b\b\b%-4d", i); + if (fread(RedP, Width, 1, f[0]) != 1 || + fread(GreenP, Width, 1, f[1]) != 1 || + fread(BlueP, Width, 1, f[2]) != 1) + GIF_EXIT("Input file(s) terminated prematurly."); + RedP += Width; + GreenP += Width; + BlueP += Width; + } + + fclose(f[0]); + fclose(f[1]); + fclose(f[2]); + } +} + +/****************************************************************************** +* Save the GIF resulting image. * +******************************************************************************/ +static void SaveGif(GifByteType *OutputBuffer, + GifColorType *OutputColorMap, + int ExpColorMapSize, int Width, int Height) +{ + int i; + GifFileType *GifFile; + GifByteType *Ptr = OutputBuffer; + + /* Open stdout for the output file: */ + if ((GifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFile); + + if (EGifPutScreenDesc(GifFile, + Width, Height, ExpColorMapSize, 0, ExpColorMapSize, + OutputColorMap) == GIF_ERROR || + EGifPutImageDesc(GifFile, + 0, 0, Width, Height, FALSE, ExpColorMapSize, NULL) == + GIF_ERROR) + QuitGifError(GifFile); + + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + for (i = 0; i < Height; i++) { + if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Height - i - 1); + + Ptr += Width; + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) + QuitGifError(GifFile); +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFile) +{ + PrintGifError(); + if (GifFile != NULL) EGifCloseFile(GifFile); + exit(1); +} diff --git a/G/UTIL/RLE2GIF.C b/G/UTIL/RLE2GIF.C new file mode 100644 index 0000000..bb61842 --- /dev/null +++ b/G/UTIL/RLE2GIF.C @@ -0,0 +1,234 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to convert RLE (utah raster toolkit) file to GIF format. * +* Options: * +* -q : quite printing mode. * +* -c #colors : in power of two, i.e. 7 will allow upto 128 colors in output. * +* -h : on line help. * +****************************************************************************** +* History: * +* 5 Jan 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#include +#include +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#include "rle.h" /* The rle tool kit header files. */ + +#define PROGRAM_NAME "Rle2Gif" + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module,\t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Rle2Gif q%- c%-#Colors!d h%- RleFile!*s"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- c%-#Colors!d h%- RleFile!*s"; +#endif /* SYSV */ + +/* Make some variables global, so we could access them faster: */ +static int + ColorFlag = FALSE, + ExpNumOfColors = 8, + HelpFlag = FALSE, + ColorMapSize = 256; + +static void LoadRle(char *FileName, + GifByteType **RedBuffer, + GifByteType **GreenBuffer, + GifByteType **BlueBuffer, + int *Width, int *Height); +static void SaveGif(GifByteType *OutputBuffer, + GifColorType *OutputColorMap, + int ExpColorMapSize, int Width, int Height); +static void QuitGifError(GifFileType *GifFile); + +/****************************************************************************** +* Interpret the command line and scan the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, Error, NumFiles, Width, Height; + char **FileName = NULL; + GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL, + *OutputBuffer = NULL; + GifColorType *OutputColorMap = NULL; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint, + &ColorFlag, &ExpNumOfColors, &HelpFlag, + &NumFiles, &FileName)) != FALSE || + (NumFiles > 1 && !HelpFlag)) { + if (Error) + GAPrintErrMsg(Error); + else if (NumFiles > 1) + GIF_MESSAGE("Error in command line parsing - one GIF file please."); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + ColorMapSize = 1 << ExpNumOfColors; + + if (NumFiles == 1) { + LoadRle(*FileName, + &RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height); + } + else { + LoadRle(NULL, + &RedBuffer, &GreenBuffer, &BlueBuffer, &Width, &Height); + } + + if ((OutputColorMap = (GifColorType *) malloc(ColorMapSize * + sizeof(GifColorType))) == NULL || + (OutputBuffer = (GifByteType *) malloc(Width * Height * + sizeof(GifByteType))) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + if (QuantizeBuffer(Width, Height, &ColorMapSize, + RedBuffer, GreenBuffer, BlueBuffer, + OutputBuffer, OutputColorMap) == GIF_ERROR) + QuitGifError(NULL); + free((char *) RedBuffer); + free((char *) GreenBuffer); + free((char *) BlueBuffer); + + SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height); +} + +/****************************************************************************** +* Load RLE file into internal frame buffer. * +******************************************************************************/ +static void LoadRle(char *FileName, + GifByteType **RedBuffer, + GifByteType **GreenBuffer, + GifByteType **BlueBuffer, + int *Width, int *Height) +{ + int i, j, k, Size; + GifByteType *OutputPtr[3]; + rle_hdr in_hdr; + rle_pixel **rows, *ptr; + + if (FileName != NULL) { + if ((in_hdr.rle_file = fopen(FileName, "r")) == NULL) + GIF_EXIT("Can't open input file name."); + } + else + in_hdr.rle_file = stdin; + + rle_get_setup_ok( &in_hdr, "rle2gif", FileName ); + + *Width = in_hdr.xmax - in_hdr.xmin + 1; + *Height = in_hdr.ymax - in_hdr.ymin + 1; + + if (in_hdr.ncolors != 3) + GIF_EXIT("Input Rle file does not hold 3 (RGB) colors, aborted."); + + Size = *Width * *Height * sizeof(GifByteType); + if (rle_row_alloc(&in_hdr, &rows) || + (*RedBuffer = (GifByteType *) malloc(Size)) == NULL || + (*GreenBuffer = (GifByteType *) malloc(Size)) == NULL || + (*BlueBuffer = (GifByteType *) malloc(Size)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + OutputPtr[0] = *RedBuffer; + OutputPtr[1] = *GreenBuffer; + OutputPtr[2] = *BlueBuffer; + + for (i = 0; i < *Height; i++) { + rle_getrow(&in_hdr, rows); /* Get one scan line (3 colors). */ + + for (j = 0; j < 3; j++) { /* Copy the 3 colors to the given buffers. */ + ptr = &rows[j][in_hdr.xmin]; + + for (k = 0; k < *Width; k++) + *OutputPtr[j]++ = *ptr++; + } + } +} + +/****************************************************************************** +* Save the GIF resulting image. * +******************************************************************************/ +static void SaveGif(GifByteType *OutputBuffer, + GifColorType *OutputColorMap, + int ExpColorMapSize, int Width, int Height) +{ + int i; + GifFileType *GifFile; + GifByteType *Ptr = OutputBuffer + Width * (Height - 1); + + /* Open stdout for the output file: */ + if ((GifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFile); + + if (EGifPutScreenDesc(GifFile, + Width, Height, ExpColorMapSize, 0, ExpColorMapSize, + OutputColorMap) == GIF_ERROR || + EGifPutImageDesc(GifFile, + 0, 0, Width, Height, FALSE, ExpColorMapSize, NULL) == + GIF_ERROR) + QuitGifError(GifFile); + + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + for (i = 0; i < Height; i++) { + if (EGifPutLine(GifFile, Ptr, Width) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", Height - i - 1); + + Ptr -= Width; + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) + QuitGifError(GifFile); +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFile) +{ + PrintGifError(); + if (GifFile != NULL) EGifCloseFile(GifFile); + exit(1); +} diff --git a/G/UTIL/TEXT2GIF.C b/G/UTIL/TEXT2GIF.C new file mode 100644 index 0000000..19a1aa7 --- /dev/null +++ b/G/UTIL/TEXT2GIF.C @@ -0,0 +1,357 @@ +/***************************************************************************** +* "Gif-Lib" - Yet another gif library. * +* * +* Written by: Gershon Elber Ver 0.1, Jul. 1989 * +****************************************************************************** +* Program to generate GIF image page from a given text by drawing the chars * +* using 8 by 8 fixed font. * +* Options: * +* -q : quite printing mode. * +* -s ColorMapSize : in bits, i.e. 6 bits for 64 colors. * +* -f ForeGroundIndex : by default foreground is 1. Must be in range 0..255. * +* -c R G B : set the foregound color values. By default it is white. * +* -t "Text" : Make one line given file (8 pixel high) from the given Text. * +* -h : on line help. * +****************************************************************************** +* History: * +* 3 May 90 - Version 1.0 by Gershon Elber. * +*****************************************************************************/ + +#ifdef __MSDOS__ +#include +#include +#endif /* __MSDOS__ */ + +#include +#include +#include +#include "gif_lib.h" +#include "getarg.h" + +#define PROGRAM_NAME "Text2Gif" + +#define MAX_NUM_TEXT_LINES 100 /* Maximum number of lines in file. */ + +#define LINE_LEN 256 /* Maximum length of one text line. */ + +#define DEFAULT_FG_INDEX 1 /* Text foreground index. */ + +#define DEFAULT_COLOR_RED 255 /* Text foreground color. */ +#define DEFAULT_COLOR_GREEN 255 +#define DEFAULT_COLOR_BLUE 255 + +#ifdef __MSDOS__ +extern unsigned int + _stklen = 16384; /* Increase default stack size. */ +#endif /* __MSDOS__ */ + +#ifdef SYSV +static char *VersionStr = + "Gif library module \t\tGershon Elber\n\ + (C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = "Text2Gif q%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-"; +#else +static char + *VersionStr = + PROGRAM_NAME + GIF_LIB_VERSION + " Gershon Elber, " + __DATE__ ", " __TIME__ "\n" + "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n"; +static char + *CtrlStr = + PROGRAM_NAME + " q%- s%-ClrMapSize!d f%-FGClr!d c%-R|G|B!d!d!d t%-\"Text\"!s h%-"; +#endif /* SYSV */ + +static unsigned int + RedColor = DEFAULT_COLOR_RED, + GreenColor = DEFAULT_COLOR_GREEN, + BlueColor = DEFAULT_COLOR_BLUE; + +/***************************************************************************** +* Ascii 8 by 8 regular font - only first 128 characters are supported. * +*****************************************************************************/ +static unsigned char AsciiTable[][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Ascii 0 */ + { 0x3c, 0x42, 0xa5, 0x81, 0xbd, 0x42, 0x3c, 0x00 }, /* Ascii 1 */ + { 0x3c, 0x7e, 0xdb, 0xff, 0xc3, 0x7e, 0x3c, 0x00 }, /* Ascii 2 */ + { 0x00, 0xee, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 3 */ + { 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 4 */ + { 0x00, 0x3c, 0x18, 0xff, 0xff, 0x08, 0x18, 0x00 }, /* Ascii 5 */ + { 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x10, 0x38, 0x00 }, /* Ascii 6 */ + { 0x00, 0x00, 0x18, 0x3c, 0x18, 0x00, 0x00, 0x00 }, /* Ascii 7 */ + { 0xff, 0xff, 0xe7, 0xc3, 0xe7, 0xff, 0xff, 0xff }, /* Ascii 8 */ + { 0x00, 0x3c, 0x42, 0x81, 0x81, 0x42, 0x3c, 0x00 }, /* Ascii 9 */ + { 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0xbd, 0xc3, 0xff }, /* Ascii 10 */ + { 0x1f, 0x07, 0x0d, 0x7c, 0xc6, 0xc6, 0x7c, 0x00 }, /* Ascii 11 */ + { 0x00, 0x7e, 0xc3, 0xc3, 0x7e, 0x18, 0x7e, 0x18 }, /* Ascii 12 */ + { 0x04, 0x06, 0x07, 0x04, 0x04, 0xfc, 0xf8, 0x00 }, /* Ascii 13 */ + { 0x0c, 0x0a, 0x0d, 0x0b, 0xf9, 0xf9, 0x1f, 0x1f }, /* Ascii 14 */ + { 0x00, 0x92, 0x7c, 0x44, 0xc6, 0x7c, 0x92, 0x00 }, /* Ascii 15 */ + { 0x00, 0x00, 0x60, 0x78, 0x7e, 0x78, 0x60, 0x00 }, /* Ascii 16 */ + { 0x00, 0x00, 0x06, 0x1e, 0x7e, 0x1e, 0x06, 0x00 }, /* Ascii 17 */ + { 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18 }, /* Ascii 18 */ + { 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 }, /* Ascii 19 */ + { 0xff, 0xb6, 0x76, 0x36, 0x36, 0x36, 0x36, 0x00 }, /* Ascii 20 */ + { 0x7e, 0xc1, 0xdc, 0x22, 0x22, 0x1f, 0x83, 0x7e }, /* Ascii 21 */ + { 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00 }, /* Ascii 22 */ + { 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x00, 0xff }, /* Ascii 23 */ + { 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* Ascii 24 */ + { 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x00 }, /* Ascii 25 */ + { 0x00, 0x04, 0x06, 0xff, 0x06, 0x04, 0x00, 0x00 }, /* Ascii 26 */ + { 0x00, 0x20, 0x60, 0xff, 0x60, 0x20, 0x00, 0x00 }, /* Ascii 27 */ + { 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0x00 }, /* Ascii 28 */ + { 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00 }, /* Ascii 29 */ + { 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00 }, /* Ascii 30 */ + { 0x00, 0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00 }, /* Ascii 31 */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */ + { 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x00 }, /* ! */ + { 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* " */ + { 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00 }, /* # */ + { 0x10, 0x7c, 0xd2, 0x7c, 0x86, 0x7c, 0x10, 0x00 }, /* $ */ + { 0xf0, 0x96, 0xfc, 0x18, 0x3e, 0x72, 0xde, 0x00 }, /* % */ + { 0x30, 0x48, 0x30, 0x78, 0xce, 0xcc, 0x78, 0x00 }, /* & */ + { 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ' */ + { 0x10, 0x60, 0xc0, 0xc0, 0xc0, 0x60, 0x10, 0x00 }, /* ( */ + { 0x10, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x10, 0x00 }, /* ) */ + { 0x00, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x00, 0x00 }, /* * */ + { 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00 }, /* + */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x70 }, /* , */ + { 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 }, /* - */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00 }, /* . */ + { 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00 }, /* / */ + { 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* 0x */ + { 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* 1 */ + { 0x7c, 0xc6, 0x06, 0x0c, 0x30, 0x60, 0xfe, 0x00 }, /* 2 */ + { 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00 }, /* 3 */ + { 0x0e, 0x1e, 0x36, 0x66, 0xfe, 0x06, 0x06, 0x00 }, /* 4 */ + { 0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xfc, 0x00 }, /* 5 */ + { 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00 }, /* 6 */ + { 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x60, 0x00 }, /* 7 */ + { 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00 }, /* 8 */ + { 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00 }, /* 9 */ + { 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 }, /* : */ + { 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x20, 0x00 }, /* }, */ + { 0x00, 0x1c, 0x30, 0x60, 0x30, 0x1c, 0x00, 0x00 }, /* < */ + { 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00 }, /* = */ + { 0x00, 0x70, 0x18, 0x0c, 0x18, 0x70, 0x00, 0x00 }, /* > */ + { 0x7c, 0xc6, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00 }, /* ? */ + { 0x7c, 0x82, 0x9a, 0xaa, 0xaa, 0x9e, 0x7c, 0x00 }, /* @ */ + { 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00 }, /* A */ + { 0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x00 }, /* B */ + { 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00 }, /* C */ + { 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00 }, /* D */ + { 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xfe, 0x00 }, /* E */ + { 0xfe, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0x00 }, /* F */ + { 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7e, 0x00 }, /* G */ + { 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00 }, /* H */ + { 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 }, /* I */ + { 0x1e, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00 }, /* J */ + { 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00 }, /* K */ + { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00 }, /* L */ + { 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0x00 }, /* M */ + { 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00 }, /* N */ + { 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* O */ + { 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00 }, /* P */ + { 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x06 }, /* Q */ + { 0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0x00 }, /* R */ + { 0x78, 0xcc, 0x60, 0x30, 0x18, 0xcc, 0x78, 0x00 }, /* S */ + { 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00 }, /* T */ + { 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* U */ + { 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 }, /* V */ + { 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00 }, /* W */ + { 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00 }, /* X */ + { 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00 }, /* Y */ + { 0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00 }, /* Z */ + { 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00 }, /* [ */ + { 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x00 }, /* \ */ + { 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00 }, /* ] */ + { 0x00, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00 }, /* ^ */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }, /* _ */ + { 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ` */ + { 0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00 }, /* a */ + { 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0x00 }, /* b */ + { 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7e, 0x00 }, /* c */ + { 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x00 }, /* d */ + { 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7e, 0x00 }, /* e */ + { 0x1e, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x30, 0x00 }, /* f */ + { 0x00, 0x00, 0x7e, 0xc6, 0xce, 0x76, 0x06, 0x7c }, /* g */ + { 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00 }, /* */ + { 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* i */ + { 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0xf0 }, /* j */ + { 0xc0, 0xc0, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0x00 }, /* k */ + { 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00 }, /* l */ + { 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xc6, 0xc6, 0x00 }, /* m */ + { 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x00 }, /* n */ + { 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00 }, /* o */ + { 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xe6, 0xdc, 0xc0 }, /* p */ + { 0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xce, 0x76, 0x06 }, /* q */ + { 0x00, 0x00, 0x6e, 0x70, 0x60, 0x60, 0x60, 0x00 }, /* r */ + { 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0xfc, 0x00 }, /* s */ + { 0x30, 0x30, 0x7c, 0x30, 0x30, 0x30, 0x1c, 0x00 }, /* t */ + { 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00 }, /* u */ + { 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 }, /* v */ + { 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x00 }, /* w */ + { 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00 }, /* x */ + { 0x00, 0x00, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0x7c }, /* y */ + { 0x00, 0x00, 0xfc, 0x18, 0x30, 0x60, 0xfc, 0x00 }, /* z */ + { 0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00 }, /* { */ + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, /* | */ + { 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00 }, /* } */ + { 0x00, 0x00, 0x70, 0x9a, 0x0e, 0x00, 0x00, 0x00 }, /* ~ */ + { 0x00, 0x00, 0x18, 0x3c, 0x66, 0xff, 0x00, 0x00 } /* Ascii 127 */ +}; + +static void QuitGifError(GifFileType *GifFile); +static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, + int BufferWidth, int ForeGroundIndex); + +/****************************************************************************** +* Interpret the command line and generate the given GIF file. * +******************************************************************************/ +void main(int argc, char **argv) +{ + int i, j, l, Error, ImageWidth, ImageHeight, NumOfLines, LogNumLevels, + NumLevels, ClrMapSizeFlag = FALSE, ColorMapSize = 1, ColorFlag = FALSE, + ForeGroundIndex = DEFAULT_FG_INDEX, ForeGroundFlag = FALSE, + TextLineFlag = FALSE, HelpFlag = FALSE; + char *TextLines[MAX_NUM_TEXT_LINES], Line[LINE_LEN]; + GifRowType RasterBuffer[8]; + GifColorType *ColorMap; + GifFileType *GifFile; + + if ((Error = GAGetArgs(argc, argv, CtrlStr, + &GifQuitePrint, &ClrMapSizeFlag, &ColorMapSize, + &ForeGroundFlag, &ForeGroundIndex, + &ColorFlag, &RedColor, &GreenColor, &BlueColor, + &TextLineFlag, &TextLines[0], + &HelpFlag)) != FALSE) { + GAPrintErrMsg(Error); + GAPrintHowTo(CtrlStr); + exit(1); + } + + if (HelpFlag) { + fprintf(stderr, VersionStr); + GAPrintHowTo(CtrlStr); + exit(0); + } + + if (ForeGroundIndex > 255 || ForeGroundIndex < 1) + GIF_EXIT("Foregound (-f) should be in the range 1..255, aborted."); + + if (ColorMapSize > 8 || ColorMapSize < 1) + GIF_EXIT("ColorMapSize (-s) should be in the range 1..8, aborted."); + + if (TextLineFlag) { + NumOfLines = 1; + ImageHeight = 8; + ImageWidth = 8 * strlen(TextLines[0]); + } + else { + NumOfLines = l = 0; + while (fgets(Line, LINE_LEN - 1, stdin)) { + for (i = strlen(Line); i > 0 && Line[i-1] <= ' '; i--); + Line[i] = 0; + if (l < i) l = i; + TextLines[NumOfLines++] = strdup(Line); + if (NumOfLines == MAX_NUM_TEXT_LINES) + GIF_EXIT("Input file has too many lines, aborted."); + } + if (NumOfLines == 0) + GIF_EXIT("No input text, aborted."); + ImageHeight = 8 * NumOfLines; + ImageWidth = 8 * l; + } + + /* Allocate the raster buffer for 8 scan lines (one text line). */ + for (i = 0; i < 8; i++) + if ((RasterBuffer[i] = (GifRowType) malloc(sizeof(GifPixelType) * + ImageWidth)) == NULL) + GIF_EXIT("Failed to allocate memory required, aborted."); + + /* Open stdout for the output file: */ + if ((GifFile = EGifOpenFileHandle(1)) == NULL) + QuitGifError(GifFile); + + /* Dump out screen description with given size and generated color map: */ + for (LogNumLevels = 1, NumLevels = 2; + NumLevels < ForeGroundIndex; + LogNumLevels++, NumLevels <<= 1); + if (NumLevels < (1 << ColorMapSize)) { + NumLevels = (1 << ColorMapSize); + LogNumLevels = ColorMapSize; + } + + if ((ColorMap = (GifColorType *) malloc(NumLevels * sizeof(GifColorType))) + == NULL) GIF_EXIT("Failed to allocate memory required, aborted."); + + for (i = 0; i < NumLevels; i++) + ColorMap[i].Red = ColorMap[i].Green = ColorMap[i].Blue = 0; + ColorMap[ForeGroundIndex].Red = RedColor; + ColorMap[ForeGroundIndex].Green = GreenColor; + ColorMap[ForeGroundIndex].Blue = BlueColor; + + if (EGifPutScreenDesc(GifFile, + ImageWidth, ImageHeight, LogNumLevels, 0, LogNumLevels, ColorMap) + == GIF_ERROR) + QuitGifError(GifFile); + + /* Dump out the image descriptor: */ + if (EGifPutImageDesc(GifFile, + 0, 0, ImageWidth, ImageHeight, FALSE, LogNumLevels, NULL) == GIF_ERROR) + QuitGifError(GifFile); + + GifQprintf("\n%s: Image 1 at (%d, %d) [%dx%d]: ", + PROGRAM_NAME, GifFile -> ILeft, GifFile -> ITop, + GifFile -> IWidth, GifFile -> IHeight); + + for (i = l = 0; i < NumOfLines; i++) { + GenRasterTextLine(RasterBuffer, TextLines[i], ImageWidth, + ForeGroundIndex); + for (j = 0; j < 8; j++) { + if (EGifPutLine(GifFile, RasterBuffer[j], ImageWidth) == GIF_ERROR) + QuitGifError(GifFile); + GifQprintf("\b\b\b\b%-4d", l++); + } + } + + if (EGifCloseFile(GifFile) == GIF_ERROR) + QuitGifError(GifFile); +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void GenRasterTextLine(GifRowType *RasterBuffer, char *TextLine, + int BufferWidth, int ForeGroundIndex) +{ + char c; + unsigned char Byte, Mask; + int i, j, k, CharPosX, Len = strlen(TextLine); + + for (i = 0; i < BufferWidth; i++) + for (j = 0; j < 8; j++) RasterBuffer[j][i] = 0; + + for (i = CharPosX = 0; i < Len; i++, CharPosX += 8) { + c = TextLine[i]; + for (j = 0; j < 8; j++) { + Byte = AsciiTable[c][j]; + for (k = 0, Mask = 128; k < 8; k++, Mask >>= 1) + if (Byte & Mask) + RasterBuffer[j][CharPosX + k] = ForeGroundIndex; + } + } +} + +/****************************************************************************** +* Close output file (if open), and exit. * +******************************************************************************/ +static void QuitGifError(GifFileType *GifFile) +{ + PrintGifError(); + if (GifFile != NULL) EGifCloseFile(GifFile); + exit(1); +} diff --git a/INT_KEY/INT_KEY.ASM b/INT_KEY/INT_KEY.ASM new file mode 100644 index 0000000..49cf464 --- /dev/null +++ b/INT_KEY/INT_KEY.ASM @@ -0,0 +1,146 @@ + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + + ASSUME CS:_TEXT + + PUBLIC DIR_MEM_TECLA + +DIR_MEM_TECLA DD 0 + + PUBLIC VECTOR_TECLADO + +VECTOR_TECLADO DD 0 + + PUBLIC GUARDA_VECTORES + +GUARDA_VECTORES PROC NEAR + PUSH AX + PUSH BX + PUSH ES + MOV AH,35h ;Guarda el vector del teclado. + MOV AL,09h + INT 21h + MOV WORD PTR CS:[VECTOR_TECLADO],BX + MOV WORD PTR CS:[VECTOR_TECLADO+2],ES + POP ES + POP BX + POP AX + RET +GUARDA_VECTORES ENDP + + PUBLIC _SET_VECTORES + +_SET_VECTORES PROC NEAR + CALL GUARDA_VECTORES + PUSH BP + MOV BP,SP + PUSH AX + PUSH DS + PUSH DX + PUSH SI + + LDS SI,[BP+4] + MOV WORD PTR CS:[DIR_MEM_TECLA],SI + MOV WORD PTR CS:[DIR_MEM_TECLA+2],DS + + MOV DX,OFFSET CS:TECLADO + MOV AX,_TEXT + MOV DS,AX + MOV AL,09h + MOV AH,25h + INT 21h ;Cambia el vector del teclado. + + POP SI + POP DX + POP DS + POP AX + POP BP + RET +_SET_VECTORES ENDP + + PUBLIC _UNSET_VECTORES + +_UNSET_VECTORES PROC NEAR + PUSH BP + MOV BP,SP + PUSH AX + PUSH DS + PUSH DX + + MOV DX,WORD PTR CS:[VECTOR_TECLADO] + MOV AX,WORD PTR CS:[VECTOR_TECLADO+2] + MOV DS,AX + MOV AL,09h + MOV AH,25h + INT 21h ;Repone el vector del teclado. + + POP DX + POP DS + POP AX + POP BP + RET +_UNSET_VECTORES ENDP + + PUBLIC TECLADO + +TECLADO PROC FAR + PUSH AX + PUSH BX + PUSH DS + PUSH SI + LDS SI,CS:[DIR_MEM_TECLA] + IN AL,60h + MOV AH,AL + IN AL,61h + OR AL,10000000b + OUT 61h,AL + AND AL,01111111b + OUT 61h,AL + MOV AL,AH + MOV BL,AL + MOV BH,00h + AND BX,007Fh + CMP AL,00h + JE TECLEADO + CMP AL,0E0h + JE TECLEADO + CMP AL,0F0h + JE TECLEADO + CMP BYTE PTR [SI],0E0h ;ltima tecla + JNE NO_DOBLE + ADD BX,128 +NO_DOBLE: TEST AL,80h + JZ NO_SOLT + MOV BYTE PTR [BX+SI],0 + JMP TECLEADO +NO_SOLT: MOV BYTE PTR [BX+SI],1 +TECLEADO: MOV [SI],AL ;ltima tecla + LDS SI,CS:[DIR_MEM_TECLA] + MOV BYTE PTR [SI+84],0 + MOV BYTE PTR [SI+85],0 + MOV AL,[SI+42] + OR AL,[SI+54] + CMP AL,1 + JNE NO_IMPR_PANT + CMP BYTE PTR [SI+55],1 + JNE NO_IMPR_PANT + MOV BYTE PTR [SI+84],1 +NO_IMPR_PANT: MOV AL,[SI+29] + OR AL,[SI+157] + CMP AL,1 + JNE NO_PAUSA + CMP BYTE PTR [SI+69],1 + JNE NO_PAUSA + MOV BYTE PTR [SI+85],1 +NO_PAUSA: MOV AL,20h + OUT 20h,AL + POP SI + POP DS + POP BX + POP AX + IRET +TECLADO ENDP + +_TEXT ends + + end \ No newline at end of file diff --git a/INT_KEY/INT_KEY.H b/INT_KEY/INT_KEY.H new file mode 100644 index 0000000..464b46f --- /dev/null +++ b/INT_KEY/INT_KEY.H @@ -0,0 +1,107 @@ +#define t_esc 1 +#define t_1 2 +#define t_2 3 +#define t_3 4 +#define t_4 5 +#define t_5 6 +#define t_6 7 +#define t_7 8 +#define t_8 9 +#define t_9 10 +#define t_0 11 +#define t_? 12 +#define t_back 14 +#define t_tab 15 +#define t_q 16 +#define t_w 17 +#define t_e 18 +#define t_r 19 +#define t_t 20 +#define t_y 21 +#define t_u 22 +#define t_i 23 +#define t_o 24 +#define t_p 25 +// [ 26 +#define t_mas 27 +#define t_enter 28 +#define t_ctrl_izq 29 +#define t_a 30 +#define t_s 31 +#define t_d 32 +#define t_f 33 +#define t_g 34 +#define t_h 35 +#define t_j 36 +#define t_k 37 +#define t_l 38 +//#define t_ 39 +// acent_o +// +#define t_shift_izq 42 +// +#define t_z 44 +#define t_x 45 +#define t_c 46 +#define t_v 47 +#define t_b 48 +#define t_n 49 +#define t_m 50 +#define t_coma 51 +#define t_pto 52 +#define t_menos 53 +#define t_shift_der 54 +#define t_por_num 55 +#define t_alt_izq 56 +#define t_space 57 +#define t_bmay 58 +#define t_f1 59 +#define t_f2 60 +#define t_f3 61 +#define t_f4 62 +#define t_f5 63 +#define t_f6 64 +#define t_f7 65 +#define t_f8 66 +#define t_f9 67 +#define t_f10 68 +#define t_bnum 69 +#define t_bdesp 70 +#define t_7n 71 +#define t_8n 72 +#define t_9n 73 +#define t_menos_num 74 +#define t_4n 75 +#define t_5n 76 +#define t_6n 77 +#define t_mas_num 78 +#define t_1n 79 +#define t_2n 80 +#define t_3n 81 +#define t_0n 82 +#define t_pto_num 83 +#define t_impr_pant 84 +#define t_pausa 85 +// <> +#define t_f11 87 +#define t_f12 88 +// Saltamos hasta 156 +#define t_intro_num 156 +#define t_ctrl_der 157 +// Saltamos hasta 180 +#define t_dividir 180 +#define t_alt_der 183 +// Saltamos a 197 +#define t_inicio 197 +#define t_arriba 198 +#define t_repag 199 +#define t_izquierda 201 +#define t_derecha 203 +#define t_fin 205 +#define t_abajo 206 +#define t_avpag 207 +#define t_ins 208 +#define t_sup 209 + +//unsigned char tecla[512]; // t_abla de det_ecciones del teclado + diff --git a/MAKE_BOT/MAKE_BO2.CPP b/MAKE_BOT/MAKE_BO2.CPP new file mode 100644 index 0000000..5d34579 --- /dev/null +++ b/MAKE_BOT/MAKE_BO2.CPP @@ -0,0 +1,1546 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "c:\things\borlandc\jd_lib\f_lib\make_bot.h" + +#define MB_TeclaPulsada() ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ) + +/**/ +/* MAKE BOTON */ +/**/ + + void ErrorOccurred(int errorcode); + + struct Make_Boton { + /* unsigned */ int Up, Left, Down, Right; + unsigned char Cdf, Cb1, Cb2; + unsigned char Ab, Pb; + unsigned char Isc, Sc; + }; + + int P_Sec(int numero); + int lee_objeto(FILE *); + void Deprime_Image(struct Make_Boton Bot_Imp); + void Imprime_Boton(int D_Bord, struct Make_Boton Bot_Imp); + + char True_Push = OFF, // Parametros para el TRUE_PUSH + Push = OFF; // PRESION REAL !!! + void far *arrow; // YA !!! + + int Secuencias, *n_Botones_Secuencia; + char memoria_asignada = 0;//, vez = 0; + + struct Make_Boton far *Botones; // Puntero a estructura + + +/**/ +/* Control del Raton */ +/**/ + + void Carga_Puntero(void); + int Carga_Puntero_Animado(void); + + void *Pantalla; + unsigned char *P_Raton1, *P_Raton2, *P_Raton3, *P_Raton4; + char raton=0, // Indica si hay un Raton = 1 + PunteroRaton=0; // Se modifica el puntero ? + + int x_raton=50, y_raton=50, // Tras Espera_Tecla_o_Raton(); devuelve + dir_raton [32+32]; // las coordenadas y botones pulsados... + + + unsigned char BLANCO = 255, GRIS_CLARO = 253, NEGRO = 240, UNKNOW = 249, AZUL = 250; + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////>>>> Inicio del codigo <<<<<='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + Secuencias = numero; + if (( n_Botones_Secuencia = (int *) malloc( sizeof(int)*Secuencias ) ) == NULL) { + printf("\nNo Hay suficiente Memoria, ni para un Boton\n\n"); + return SIN_MEMORIA; + } + } + + if (ch=='!') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + temp_num = numero; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + n_Botones_Secuencia[temp_num - 1] = numero; + + SiZe_BoToN += ( sizeof( struct Make_Boton ) * numero); + + if ( (Botones = (struct Make_Boton far *)farrealloc(Botones, SiZe_BoToN )) == NULL) { + Secuencias = temp_num; + return SIN_MEMORIA; + } + memoria_asignada = 1; + } + if (ch=='$') { //Clculos del boton + inc_Botones++; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Left = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Up = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Right =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + if(ch == '-' || ch == '-') signo = 1; + ch=fgetc(fichero); + } + if ( signo == 1 ) + Botones [inc_Botones]. Down =numero * -1; + else + Botones [inc_Botones]. Down =numero; + signo = 0; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cdf =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cb1 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cb2 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Ab =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Pb =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Isc =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Sc =numero; + + } + + if (ch!=EOF) ch=fgetc(fichero); + } + + return OK; +} + + +void despliega_datos(void){ + int SeCa; + + clrscr(); + for(int SeC=0; SeC 0) + { + puntos[1] = 120; + puntos[2] = 300; + } else { + puntos[1] = 60; + puntos[2] = 240; + } + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[1]+puntos[0], puntos[2]+puntos[0], Bot_Imp.Right - puntos[0]); + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[2]+puntos[0], puntos[1]+puntos[0], Bot_Imp.Right - puntos[0]); + + if(D_Bord) { + setcolor(Bot_Imp.Cdf); + setfillstyle(SOLID_FILL, Bot_Imp.Cdf); + pieslice( Bot_Imp.Left, Bot_Imp.Up, 0, 360, Bot_Imp.Right - Ab); + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + circle( Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right); + } + + } else { + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right; puntos[5] = Bot_Imp.Down; + puntos[6] = (Bot_Imp.Right-Ab); puntos[7] = (Bot_Imp.Down-Ab); + puntos[8] = (Bot_Imp.Right-Ab); puntos[9] = (Bot_Imp.Up+Ab); + puntos[10] = (Bot_Imp.Left+Ab); puntos[11] = (Bot_Imp.Up+Ab); + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } else { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right - Ab; puntos[5] = Bot_Imp.Up + Ab; + puntos[6] = Bot_Imp.Left + Ab; puntos[7] = Bot_Imp.Up + Ab; + puntos[8] = Bot_Imp.Left + Ab; puntos[9] = Bot_Imp.Down - Ab; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Down; + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left+Ab; puntos[1] = Bot_Imp.Up+Ab; + puntos[2] = Bot_Imp.Left+Ab; puntos[3] = Bot_Imp.Down-Ab; + puntos[4] = Bot_Imp.Right-Ab; puntos[5] = Bot_Imp.Down-Ab; + puntos[6] = Bot_Imp.Right; puntos[7] = Bot_Imp.Down; + puntos[8] = Bot_Imp.Left; puntos[9] = Bot_Imp.Down; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Up; + puntos[12] = Bot_Imp.Left+Ab; puntos[13] = Bot_Imp.Up+Ab; + } else { + puntos[0] = Bot_Imp.Right; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Down; + puntos[4] = Bot_Imp.Left; puntos[5] = Bot_Imp.Down; + puntos[6] = Bot_Imp.Left+Ab; puntos[7] = Bot_Imp.Down-Ab; + puntos[8] = Bot_Imp.Right-Ab; puntos[9] = Bot_Imp.Down-Ab; + puntos[10] = Bot_Imp.Right-Ab; puntos[11] = Bot_Imp.Up+Ab; + puntos[12] = Bot_Imp.Right; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if(D_Bord) { + setcolor(Bot_Imp.Cdf); + setfillstyle(SOLID_FILL, Bot_Imp.Cdf); + bar(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1); + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + rectangle(Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right, Bot_Imp.Down); + } +} + +} + +void Imprime_Boton_i(struct Make_Boton Bot_Imp){ + + int puntos[14]; + unsigned char Ab = Bot_Imp.Ab; + unsigned long size; + +if ( Bot_Imp.Down < 0 ) + { + if(Bot_Imp.Pb > 0) + { + puntos[1] = 120; + puntos[2] = 300; + } else { + puntos[1] = 60; + puntos[2] = 240; + } + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[1]+puntos[0], puntos[2]+puntos[0], Bot_Imp.Right - puntos[0]); + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[2]+puntos[0], puntos[1]+puntos[0], Bot_Imp.Right - puntos[0]); + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + circle( Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right); + } + + } else { + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right; puntos[5] = Bot_Imp.Down; + puntos[6] = (Bot_Imp.Right-Ab); puntos[7] = (Bot_Imp.Down-Ab); + puntos[8] = (Bot_Imp.Right-Ab); puntos[9] = (Bot_Imp.Up+Ab); + puntos[10] = (Bot_Imp.Left+Ab); puntos[11] = (Bot_Imp.Up+Ab); + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } else { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right - Ab; puntos[5] = Bot_Imp.Up + Ab; + puntos[6] = Bot_Imp.Left + Ab; puntos[7] = Bot_Imp.Up + Ab; + puntos[8] = Bot_Imp.Left + Ab; puntos[9] = Bot_Imp.Down - Ab; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Down; + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + /* calculate the size of the image */ + size = JD_imagesize(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1); + + /* allocate memory to hold the image */ + if (True_Push == ON) + if ( (arrow = farmalloc(size)) == NULL ) Push = OFF; else { + /* grab the image */ + getimage(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1, arrow); + } + + if(Push == ON && True_Push == ON ) { + if(Bot_Imp.Pb == 2) { + putimage(Bot_Imp.Left+1, Bot_Imp.Up+(Ab*2), arrow, COPY_PUT); + } else { + putimage(Bot_Imp.Left+(Ab*2), Bot_Imp.Up+(Ab*2), arrow, COPY_PUT); + } + } else { + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left+Ab; puntos[1] = Bot_Imp.Up+Ab; + puntos[2] = Bot_Imp.Left+Ab; puntos[3] = Bot_Imp.Down-Ab; + puntos[4] = Bot_Imp.Right-Ab; puntos[5] = Bot_Imp.Down-Ab; + puntos[6] = Bot_Imp.Right; puntos[7] = Bot_Imp.Down; + puntos[8] = Bot_Imp.Left; puntos[9] = Bot_Imp.Down; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Up; + puntos[12] = Bot_Imp.Left+Ab; puntos[13] = Bot_Imp.Up+Ab; + } else { + puntos[0] = Bot_Imp.Right; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Down; + puntos[4] = Bot_Imp.Left; puntos[5] = Bot_Imp.Down; + puntos[6] = Bot_Imp.Left+Ab; puntos[7] = Bot_Imp.Down-Ab; + puntos[8] = Bot_Imp.Right-Ab; puntos[9] = Bot_Imp.Down-Ab; + puntos[10] = Bot_Imp.Right-Ab; puntos[11] = Bot_Imp.Up+Ab; + puntos[12] = Bot_Imp.Right; puntos[13] = Bot_Imp.Up; + } + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + rectangle(Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right, Bot_Imp.Down); + } +} + +} + +// +// + +void Deprime_Image(struct Make_Boton Bot_Imp){ + putimage(Bot_Imp.Left+Bot_Imp.Ab+1, Bot_Imp.Up+Bot_Imp.Ab+1, arrow, COPY_PUT); + farfree(arrow); +} + +// +// + +int Imprime_Estaticos(int Sec_st, char *file){ + + char ch, Relleno = 1, buffer[160]; + unsigned char fuente, size, orientacion, color, + signo=0; + unsigned int /*numero, */ temp_num, temp_b; + int numero; + + int secuencia_activa=-1, x, y; + + struct Make_Boton Bot_Static; + + FILE* fichero; // Fichero con datos del obj. + + if ( (fichero=fopen(file,"r"))==NULL ) return ERROR_ABRIENDO; + + ch=fgetc(fichero); //Lee el primer caracter + while (ch!=EOF) { //Lee hasta fin de fichero + + if (ch=='*') //Linea con comentario + while (ch!=EOL && ch!=EOF) ch=fgetc(fichero); + + if (ch=='') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + secuencia_activa = numero; + } + + if (ch=='&' && secuencia_activa == Sec_st) { //Clculos del boton estatico + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Left = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Up = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Right =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + if(ch == '-' || ch == '-') signo = 1; + ch=fgetc(fichero); + } + if ( signo==1 ) + Bot_Static.Down =numero * -1; + else + Bot_Static.Down =numero; + signo = 0; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cdf =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cb1 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cb2 =numero; + + numero=0; Relleno = 1; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; else + if(ch == '-' || ch == '-') Relleno = 0; + ch=fgetc(fichero); + } + Bot_Static.Ab =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Pb =numero; + Imprime_Boton(Relleno, Bot_Static); + } + if (ch=='|' && secuencia_activa == Sec_st) { //Clculos del texto + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + x = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + y = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fuente = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + size = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + orientacion = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + color = numero; + + buffer[0] = '\0'; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',' && numero<150 ) { + ch=fgetc(fichero); + if(ch!=',') { buffer[numero] = ch; numero++; } + } + + buffer[numero] = '\0'; + setcolor(color); + /* select the registered font */ + settextstyle( fuente, orientacion, size); + outtextxy(x, y, buffer); + + + } + + + if (ch!=EOF) ch=fgetc(fichero); + } + + if( fclose(fichero) != 0 ) return ERROR_CERRANDO; + return OK; +} + +void Imprime_Secuencia(int Sec_num){ + int psec = P_Sec(Sec_num-1); + for(int i=0; in_Botones_Secuencia[Sec_num-1] ) return; + + Boton--; + + if( Color < 0 ) + { + Imprime_Boton( 0, Botones[psec+Boton] ); + return; + } + +if ( Botones[psec+Boton].Down < 0 ) + { + + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + for ( puntos[0] = 0; puntos[0] < Botones[psec+Boton].Ab; puntos[0]++ ) + circle( Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right - puntos[0]); + + if( Botones[psec+Boton].Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Botones[psec+Boton].Cdf); + circle( Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right); + } + + } else { + + puntos[0] = Botones[psec+Boton].Left; puntos[1] = Botones[psec+Boton].Up; + puntos[2] = Botones[psec+Boton].Right; puntos[3] = Botones[psec+Boton].Up; + puntos[4] = Botones[psec+Boton].Right; puntos[5] = Botones[psec+Boton].Down; + puntos[6] = (Botones[psec+Boton].Right-Botones[psec+Boton].Ab); puntos[7] = (Botones[psec+Boton].Down-Botones[psec+Boton].Ab); + puntos[8] = (Botones[psec+Boton].Right-Botones[psec+Boton].Ab); puntos[9] = (Botones[psec+Boton].Up+Botones[psec+Boton].Ab); + puntos[10] = (Botones[psec+Boton].Left+Botones[psec+Boton].Ab); puntos[11] = (Botones[psec+Boton].Up+Botones[psec+Boton].Ab); + puntos[12] = Botones[psec+Boton].Left; puntos[13] = Botones[psec+Boton].Up; + + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + puntos[0] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[1] = Botones[psec+Boton].Up+Botones[psec+Boton].Ab; + puntos[2] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[3] = Botones[psec+Boton].Down-Botones[psec+Boton].Ab; + puntos[4] = Botones[psec+Boton].Right-Botones[psec+Boton].Ab; puntos[5] = Botones[psec+Boton].Down-Botones[psec+Boton].Ab; + puntos[6] = Botones[psec+Boton].Right; puntos[7] = Botones[psec+Boton].Down; + puntos[8] = Botones[psec+Boton].Left; puntos[9] = Botones[psec+Boton].Down; + puntos[10] = Botones[psec+Boton].Left; puntos[11] = Botones[psec+Boton].Up; + puntos[12] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[13] = Botones[psec+Boton].Up+Botones[psec+Boton].Ab; + + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if( Botones[psec+Boton].Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Botones[psec+Boton].Cdf); + rectangle(Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right, Botones[psec+Boton].Down); + } +} + +} + + +int Comprueba_Secuencia(int Sec_num){ + + char key, key2=0; + int i, Pulso = 0; + int psec = P_Sec(Sec_num-1); + + + + if ( Espera_Tecla_o_Raton() == 0 ) { + + if ( (key = getch())==0) key2 = getch(); + for(i=0; i= Botones[psec+i].Left - Botones[psec+i].Right) && (x_raton <= Botones[psec+i].Left + Botones[psec+i].Right) && + (y_raton >= Botones[psec+i].Up - Botones[psec+i].Right) && (y_raton <= Botones[psec+i].Up + Botones[psec+i].Right) ) { + + Pulso = i + 1; + Push = ON; + Imprime_Boton_i(Botones[psec+Pulso-1]); + Anclar_Raton(); + if( Push == ON && True_Push == ON ) Deprime_Image(Botones[psec+Pulso-1]); + Push = OFF; + Imprime_Boton(0, Botones[psec+Pulso-1]); + return Pulso; + } + else + if( (x_raton >= Botones[psec+i].Left) && (x_raton <= Botones[psec+i].Right) && + (y_raton >= Botones[psec+i].Up) && (y_raton <= Botones[psec+i].Down) ) { + + Pulso = i + 1; + Push = ON; + Imprime_Boton_i(Botones[psec+Pulso-1]); + Anclar_Raton(); + if( Push == ON && True_Push == ON ) Deprime_Image(Botones[psec+Pulso-1]); + Push = OFF; + Imprime_Boton(0, Botones[psec+Pulso-1]); + return Pulso; + } + + return (0); +} + + +void Anclar_Raton(void){ + + union REGS io; + io.x.ax = 3; + do { + int86(0x33, &io, &io); + } while( (io.x.bx & 1)==1 || ((io.x.bx >> 1) & 1)==1); +} + + +int Espera_TeclaRaton(void){ + +// inicializa_raton_grafico(0, 0, 624, 464); +// char boton_izq, boton_der; + char Que; + activa_raton(); + + union REGS io; + io.x.ax = 3; + + do{ + int86(0x33, &io, &io); // lee posicin y estados del botn +// boton_izq = io.x.bx & 1; +// boton_der = (io.x.bx >> 1) & 1; + x_raton = io.x.cx; + y_raton = io.x.dx; + + }while( (io.x.bx & 1) == 0 && ((io.x.bx >> 1) & 1) == 0 && !MB_TeclaPulsada() ); + + + + + ///////////////////////////////////////// + // RETURN Derecho Izquierdo // + // // + // 0 0 0 // + // 1 1 0 // + // 2 0 1 // + // 3 1 1 // + // // + ///////////////////////////////////////// + + + if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==0 ) Que = 0; + if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==0 ) Que = 1; + if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==1 ) Que = 2; + if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==1 ) Que = 3; + + desactiva_raton(); + return Que; +} + + + + +void inicializa_raton_grafico(int x1, int y1, int x2, int y2) +{ + +int px = x_raton, py = y_raton; + + struct SREGS seg; + union REGS ent, sal; + long dir; + + ent.x.ax = 0; + int86(0x33, &ent, &sal); /* averigua si hay ratn conectado */ + + raton = sal.x.ax; /* indica a la variable global el estado + del raton */ + + if(raton!=0) { + + + ent.x.ax = 15; + ent.x.cx = 5; + ent.x.dx = 11; + int86(0x33, &ent, &sal); /* fija la razn mickey/pixel */ + + ent.x.ax = 7; + ent.x.cx = x1; + ent.x.dx = x2; + int86(0x33, &ent, &sal); /* fija la posicin mx. y mn. horizontal */ + + ent.x.ax = 8; + ent.x.cx = y1; + ent.x.dx = y2; + int86(0x33, &ent, &sal); /* fija la posicin mx. y mn. vertical */ + + if ( PunteroRaton == 100 ) { + if ( Carga_Puntero_Animado() ) { PunteroRaton = 1; Carga_Puntero(); } +} else Carga_Puntero(); + + if( PunteroRaton != 100 && PunteroRaton != 0) { + dir = (long)dir_raton; + ent.x.ax = 9; + ent.x.bx = 0; + ent.x.cx = 0; + ent.x.dx = (int) dir; + seg.es = (int) (dir >> 16); + int86x(0x33, &ent, &sal, &seg); /* asigna un cursor diferente */ + } + + ent.x.ax = 4; + ent.x.cx = px; + x_raton=ent.x.cx >> 1; + ent.x.dx = py; + y_raton=ent.x.dx; + int86(0x33, &ent, &sal); /* fija la posicin del ratn */ + + ent.x.ax = 1; + +if( PunteroRaton != 100 ) + int86(0x33, &ent, &sal); /* muestra el puntero del ratn */ + + desactiva_raton(); + + } +} + +void activa_raton(void) +{ + union REGS ent; + + ent.x.ax = 1; + int86(0x33, &ent, &ent); +} + +void desactiva_raton(void) +{ + union REGS ent; + + ent.x.ax = 2; + int86(0x33, &ent, &ent); +} + + + + + +void Initialize(int GraphDriver, int GraphMode) +{ + int errorcode; + +/* + if( (errorcode = registerbgifont(SMALL_FONT)) < 0 ) + ErrorOccurred(errorcode); +*/ + + /* report any registration errors */ +/* if ( (errorcode = registerbgidriver(EGAVGA_driver) ) < 0) + ErrorOccurred(errorcode); +*/ + /* initialize graphics and local variables */ + initgraph( &GraphDriver, &GraphMode, "" ); + + /* read result of initialization */ + errorcode = graphresult(); + if (errorcode != grOk) /* an error occurred */ + ErrorOccurred(errorcode); + + +} + +void ErrorOccurred(int errorcode) { + printf("Graphics error: %s\n", grapherrormsg(errorcode)); + printf("Press any key to halt:"); + getch(); + exit(1); /* terminate with an error code */ +} + +void Libera_Memoria(void){ + if ( memoria_asignada == 1 ) { // Libera antiguos datos + free(n_Botones_Secuencia); + farfree(Botones); + memoria_asignada = 0; + } +} + + +int Espera_Tecla_o_Raton(void){ + +// inicializa_raton_grafico(0, 0, 624, 464); +char Vez_Raton; int x, y; +char boton_izq=0, boton_der=0; +char Que; +// static char vez = 0; + +Vez_Raton = 0; + +union REGS io; + +if ( PunteroRaton!=100 ){ return Espera_TeclaRaton(); } + +if(raton!=0) { + desactiva_raton(); + io.x.ax = 3; +} + + do{ + if(raton!=0) { + int86(0x33, &io, &io); // lee posicin y estados del botn + boton_izq = io.x.bx & 1; + boton_der = (io.x.bx >> 1) & 1; + if ( x_raton != io.x.cx || y_raton != io.x.dx ) { + if(Vez_Raton==0) Vez_Raton = 1; else + putimage(x_raton, y_raton, Pantalla, COPY_PUT); + x_raton = io.x.cx; + y_raton = io.x.dx; + getimage(x_raton, y_raton, x_raton+21, y_raton+21, Pantalla); + + if( Vez_Raton ==14 ) { Vez_Raton = 1; } + if( Vez_Raton ==13 ) { Vez_Raton =14; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton ==12 ) { Vez_Raton =13; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton ==11 ) { Vez_Raton =12; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton ==10 ) { Vez_Raton =11; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 9 ) { Vez_Raton =10; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 8 ) { Vez_Raton = 9; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 7 ) { Vez_Raton = 8; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 6 ) { Vez_Raton = 7; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 5 ) { Vez_Raton = 6; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 4 ) { Vez_Raton = 5; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton == 3 ) { Vez_Raton = 4; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton == 2 ) { Vez_Raton = 3; // putimage(x_raton, y_raton, P_Raton1, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton1[x+y*20] != 253) putpixel(x_raton + x, y_raton + y, P_Raton1[x+y*20]); + + } + if( Vez_Raton == 1 ) { Vez_Raton = 2; // putimage(x_raton, y_raton, P_Raton1, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton1[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton1[x+y*20]); + + } + +/* + if( Vez_Raton == 1 ) { Vez_Raton = 1; + + for(y=0; y<=20; y++) + for(x=0; x<=20; x++) + if( P_Raton1[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton1[4+x+y*20]); + putimage(x_raton, y_raton, P_Raton1, 0); + + } +*/ + } + } + }while( boton_izq == 0 && boton_der == 0 && !MB_TeclaPulsada() ); + +if( raton!=0 ) + putimage(x_raton, y_raton, Pantalla, COPY_PUT); + + + + ///////////////////////////////////////// + // RETURN Derecho Izquierdo // + // // + // 0 0 0 // + // 1 1 0 // + // 2 0 1 // + // 3 1 1 // + // // + ///////////////////////////////////////// + + + if ( boton_der==0 && boton_izq==0 ) Que = 0; + if ( boton_der==1 && boton_izq==0 ) Que = 1; + if ( boton_der==0 && boton_izq==1 ) Que = 2; + if ( boton_der==1 && boton_izq==1 ) Que = 3; +/* +if(raton!=0) + activa_raton(); +*/ + return Que; +} + + +unsigned long JD_imagesize(int left, int top, int right, int bottom) { + + unsigned long X_width, Y_width; + + X_width= ( (left > right) ? (left - right + 1) : ( right - left + 1) ); + Y_width= ( ( top > bottom) ? ( top - bottom + 1) : (bottom - top + 1) ); + + return (X_width * Y_width + 4); + +}; + + +void Libera_Raton_Animado(void){ + + +if ( PunteroRaton == 100 ) { + free(P_Raton1); + free(P_Raton2); + free(P_Raton3); + free(P_Raton4); + free(Pantalla); +} + +} + +void Carga_Puntero(void){ + + switch( PunteroRaton ) { + + case 0: + break; + case 1: + dir_raton [ 0] = 0x007F; /* 1 1 1 1 1 1 1*/ + dir_raton [ 1] = 0x00FF; /* 1 1 1 1 1 1 1 1*/ + dir_raton [ 2] = 0x01FF; /* 1 1 1 1 1 1 1 1 1*/ + dir_raton [ 3] = 0x01FF; /* 1 1 1 1 1 1 1 1 1*/ + dir_raton [ 4] = 0x00FF; /* 1 1 1 1 1 1 1 1*/ + dir_raton [ 5] = 0x007F; /* 1 1 1 1 1 1 1*/ + dir_raton [ 6] = 0x18FF; /* 1 1 1 1 1 1 1 1 1 1*/ + + dir_raton [ 7] = 0x800F; /*1 1 1 1 1*/ + dir_raton [ 8] = 0x8083; /*1 1 1*/ + dir_raton [ 9] = 0x8001; /*1 1*/ + dir_raton [10] = 0xF810; /*1 1 1 1 1 1 1*/ + dir_raton [11] = 0x8810; /*1 1 1 1*/ + dir_raton [12] = 0x8811; /*1 1 1 1*/ + dir_raton [13] = 0x8003; /*1 1 1*/ + dir_raton [14] = 0x8007; /*1 1 1 1*/ + dir_raton [15] = 0x800F; /*1 1 1 1 1*/ + + dir_raton [16] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [17] = 0x7E00; /*0 0 0 0 0 0 0 0 0 0*/ + dir_raton [18] = 0x7C00; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [19] = 0x7C00; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [20] = 0x7E00; /*0 0 0 0 0 0 0 0 0 0*/ + dir_raton [21] = 0x6700; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [22] = 0x0200; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + + dir_raton [23] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [24] = 0x3E70; /*0 0 0 0 0 0 0 0*/ + dir_raton [25] = 0x0248; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [26] = 0x0244; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [27] = 0x0242; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [28] = 0x2244; /*0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [29] = 0x2248; /*0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [30] = 0x3E70; /*0 0 0 0 0 0 0 0*/ + dir_raton [31] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + }; + + +}; + +int Carga_Puntero_Animado(void) { + + +// char *P_Raton; +if( ((P_Raton1 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton2 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton3 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton4 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) ) { + return 1; + } + +if ( (Pantalla = malloc( JD_imagesize(0, 0, 22, 22) )) == NULL ) + return 1; +/* +P_Raton = P_Raton1; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton2; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton3; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton4; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*/ +return 0; +} + + +/// int MB_TeclaPulsada(void) +/* Esta funcin mira si se ha pulsado una tecla pero SIN llamadas a la BIOS, + de forma que no se inhabilitan las interrupciones en cada llamada, cosa + que bajara mucho la calidad de reproduccin con el altavoz interno. */ +/// { +/// return ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ); +/// } + + +aton == 8 ) { Vez_Raton = 9; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 7 ) { Vez_Raton = 8; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; \ No newline at end of file diff --git a/MAKE_BOT/MAKE_BOT.CPP b/MAKE_BOT/MAKE_BOT.CPP new file mode 100644 index 0000000..3f3031e --- /dev/null +++ b/MAKE_BOT/MAKE_BOT.CPP @@ -0,0 +1,1523 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "d:\program\src_dos\libs\make_bot\make_bot.h" + +#define MB_TeclaPulsada() ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ) + +/**/ +/* MAKE BOTON */ +/**/ + + void ErrorOccurred(int errorcode); + + struct Make_Boton { + /* unsigned */ int Up, Left, Down, Right; + unsigned char Cdf, Cb1, Cb2; + unsigned char Ab, Pb; + unsigned char Isc, Sc; + }; + + int P_Sec(int numero); + int lee_objeto(FILE *); + void Deprime_Image(struct Make_Boton Bot_Imp); + void Imprime_Boton(int D_Bord, struct Make_Boton Bot_Imp); + + char True_Push = OFF, // Parametros para el TRUE_PUSH + Push = OFF; // PRESION REAL !!! + void far *arrow; // YA !!! + + int Secuencias, *n_Botones_Secuencia; + char memoria_asignada = 0;//, vez = 0; + + struct Make_Boton far *Botones; // Puntero a estructura + + +/**/ +/* Control del Raton */ +/**/ + + void Carga_Puntero(void); + int Carga_Puntero_Animado(void); + + void *Pantalla; + unsigned char *P_Raton1, *P_Raton2, *P_Raton3, *P_Raton4; + char raton=0, // Indica si hay un Raton = 1 + PunteroRaton=0; // Se modifica el puntero ? + + int x_raton=50, y_raton=50, // Tras Espera_Tecla_o_Raton(); devuelve + dir_raton [32+32]; // las coordenadas y botones pulsados... + + + unsigned char BLANCO = 255, GRIS_CLARO = 253, NEGRO = 240, UNKNOW = 249, AZUL = 250; + +////////////////////////////////////////////////////////////////////////////// +/////////////////////////>>>> Inicio del codigo <<<<<='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + Secuencias = numero; + if (( n_Botones_Secuencia = (int *) malloc( sizeof(int)*Secuencias ) ) == NULL) { + printf("\nNo Hay suficiente Memoria, ni para un Boton\n\n"); + return SIN_MEMORIA; + } + } + + if (ch=='!') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + temp_num = numero; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + n_Botones_Secuencia[temp_num - 1] = numero; + + SiZe_BoToN += ( sizeof( struct Make_Boton ) * numero); + + if ( (Botones = (struct Make_Boton far *)farrealloc(Botones, SiZe_BoToN )) == NULL) { + Secuencias = temp_num; + return SIN_MEMORIA; + } + memoria_asignada = 1; + } + if (ch=='$') { //Clculos del boton + inc_Botones++; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Left = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Up = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Right =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + if(ch == '-' || ch == '-') signo = 1; + ch=fgetc(fichero); + } + if ( signo == 1 ) + Botones [inc_Botones]. Down =numero * -1; + else + Botones [inc_Botones]. Down =numero; + signo = 0; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cdf =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cb1 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Cb2 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Ab =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Pb =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Isc =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Botones [inc_Botones]. Sc =numero; + + } + + if (ch!=EOF) ch=fgetc(fichero); + } + + return OK; +} + + +void despliega_datos(void){ + int SeCa; + + clrscr(); + for(int SeC=0; SeC<=Secuencias; SeC++){ + SeCa = P_Sec(SeC); + for(int Sec_S=0; Sec_S 0) + { + puntos[1] = 120; + puntos[2] = 300; + } else { + puntos[1] = 60; + puntos[2] = 240; + } + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[1]+puntos[0], puntos[2]+puntos[0], Bot_Imp.Right - puntos[0]); + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[2]+puntos[0], puntos[1]+puntos[0], Bot_Imp.Right - puntos[0]); + + if(D_Bord) { + setcolor(Bot_Imp.Cdf); + setfillstyle(SOLID_FILL, Bot_Imp.Cdf); + pieslice( Bot_Imp.Left, Bot_Imp.Up, 0, 360, Bot_Imp.Right - Ab); + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + circle( Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right); + } + + } else { + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right; puntos[5] = Bot_Imp.Down; + puntos[6] = (Bot_Imp.Right-Ab); puntos[7] = (Bot_Imp.Down-Ab); + puntos[8] = (Bot_Imp.Right-Ab); puntos[9] = (Bot_Imp.Up+Ab); + puntos[10] = (Bot_Imp.Left+Ab); puntos[11] = (Bot_Imp.Up+Ab); + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } else { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right - Ab; puntos[5] = Bot_Imp.Up + Ab; + puntos[6] = Bot_Imp.Left + Ab; puntos[7] = Bot_Imp.Up + Ab; + puntos[8] = Bot_Imp.Left + Ab; puntos[9] = Bot_Imp.Down - Ab; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Down; + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left+Ab; puntos[1] = Bot_Imp.Up+Ab; + puntos[2] = Bot_Imp.Left+Ab; puntos[3] = Bot_Imp.Down-Ab; + puntos[4] = Bot_Imp.Right-Ab; puntos[5] = Bot_Imp.Down-Ab; + puntos[6] = Bot_Imp.Right; puntos[7] = Bot_Imp.Down; + puntos[8] = Bot_Imp.Left; puntos[9] = Bot_Imp.Down; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Up; + puntos[12] = Bot_Imp.Left+Ab; puntos[13] = Bot_Imp.Up+Ab; + } else { + puntos[0] = Bot_Imp.Right; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Down; + puntos[4] = Bot_Imp.Left; puntos[5] = Bot_Imp.Down; + puntos[6] = Bot_Imp.Left+Ab; puntos[7] = Bot_Imp.Down-Ab; + puntos[8] = Bot_Imp.Right-Ab; puntos[9] = Bot_Imp.Down-Ab; + puntos[10] = Bot_Imp.Right-Ab; puntos[11] = Bot_Imp.Up+Ab; + puntos[12] = Bot_Imp.Right; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if(D_Bord) { + setcolor(Bot_Imp.Cdf); + setfillstyle(SOLID_FILL, Bot_Imp.Cdf); + bar(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1); + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + rectangle(Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right, Bot_Imp.Down); + } +} + +} + +void Imprime_Boton_i(struct Make_Boton Bot_Imp){ + + int puntos[14]; + unsigned char Ab = Bot_Imp.Ab; + unsigned long size; + +if ( Bot_Imp.Down < 0 ) + { + if(Bot_Imp.Pb > 0) + { + puntos[1] = 120; + puntos[2] = 300; + } else { + puntos[1] = 60; + puntos[2] = 240; + } + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[1]+puntos[0], puntos[2]+puntos[0], Bot_Imp.Right - puntos[0]); + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + for ( puntos[0] = 0; puntos[0] < Ab; puntos[0]++ ) + arc( Bot_Imp.Left, Bot_Imp.Up, puntos[2]+puntos[0], puntos[1]+puntos[0], Bot_Imp.Right - puntos[0]); + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + circle( Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right); + } + + } else { + + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right; puntos[5] = Bot_Imp.Down; + puntos[6] = (Bot_Imp.Right-Ab); puntos[7] = (Bot_Imp.Down-Ab); + puntos[8] = (Bot_Imp.Right-Ab); puntos[9] = (Bot_Imp.Up+Ab); + puntos[10] = (Bot_Imp.Left+Ab); puntos[11] = (Bot_Imp.Up+Ab); + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } else { + puntos[0] = Bot_Imp.Left; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Up; + puntos[4] = Bot_Imp.Right - Ab; puntos[5] = Bot_Imp.Up + Ab; + puntos[6] = Bot_Imp.Left + Ab; puntos[7] = Bot_Imp.Up + Ab; + puntos[8] = Bot_Imp.Left + Ab; puntos[9] = Bot_Imp.Down - Ab; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Down; + puntos[12] = Bot_Imp.Left; puntos[13] = Bot_Imp.Up; + } + + setcolor(Bot_Imp.Cb2); + setfillstyle(SOLID_FILL, Bot_Imp.Cb2); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + /* calculate the size of the image */ + size = JD_imagesize(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1); + + /* allocate memory to hold the image */ + if (True_Push == ON) + if ( (arrow = farmalloc(size)) == NULL ) Push = OFF; else { + /* grab the image */ + getimage(Bot_Imp.Left+Ab+1, Bot_Imp.Up+Ab+1, Bot_Imp.Right-Ab-1, Bot_Imp.Down-Ab-1, arrow); + } + + if(Push == ON && True_Push == ON ) { + if(Bot_Imp.Pb == 2) { + putimage(Bot_Imp.Left+1, Bot_Imp.Up+(Ab*2), arrow, COPY_PUT); + } else { + putimage(Bot_Imp.Left+(Ab*2), Bot_Imp.Up+(Ab*2), arrow, COPY_PUT); + } + } else { + if(Bot_Imp.Pb == 2) { + puntos[0] = Bot_Imp.Left+Ab; puntos[1] = Bot_Imp.Up+Ab; + puntos[2] = Bot_Imp.Left+Ab; puntos[3] = Bot_Imp.Down-Ab; + puntos[4] = Bot_Imp.Right-Ab; puntos[5] = Bot_Imp.Down-Ab; + puntos[6] = Bot_Imp.Right; puntos[7] = Bot_Imp.Down; + puntos[8] = Bot_Imp.Left; puntos[9] = Bot_Imp.Down; + puntos[10] = Bot_Imp.Left; puntos[11] = Bot_Imp.Up; + puntos[12] = Bot_Imp.Left+Ab; puntos[13] = Bot_Imp.Up+Ab; + } else { + puntos[0] = Bot_Imp.Right; puntos[1] = Bot_Imp.Up; + puntos[2] = Bot_Imp.Right; puntos[3] = Bot_Imp.Down; + puntos[4] = Bot_Imp.Left; puntos[5] = Bot_Imp.Down; + puntos[6] = Bot_Imp.Left+Ab; puntos[7] = Bot_Imp.Down-Ab; + puntos[8] = Bot_Imp.Right-Ab; puntos[9] = Bot_Imp.Down-Ab; + puntos[10] = Bot_Imp.Right-Ab; puntos[11] = Bot_Imp.Up+Ab; + puntos[12] = Bot_Imp.Right; puntos[13] = Bot_Imp.Up; + } + setcolor(Bot_Imp.Cb1); + setfillstyle(SOLID_FILL, Bot_Imp.Cb1); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + } + + if( Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Bot_Imp.Cdf); + rectangle(Bot_Imp.Left, Bot_Imp.Up, Bot_Imp.Right, Bot_Imp.Down); + } +} + +} + +// +// + +void Deprime_Image(struct Make_Boton Bot_Imp){ + putimage(Bot_Imp.Left+Bot_Imp.Ab+1, Bot_Imp.Up+Bot_Imp.Ab+1, arrow, COPY_PUT); + farfree(arrow); +} + +// +// + +int Imprime_Estaticos(int Sec_st, char *file){ + + char ch, Relleno = 1, buffer[160]; + unsigned char fuente, size, orientacion, color, + signo=0; + unsigned int /*numero, */ temp_num, temp_b; + int numero; + + int secuencia_activa=-1, x, y; + + struct Make_Boton Bot_Static; + + FILE* fichero; // Fichero con datos del obj. + + if ( (fichero=fopen(file,"r"))==NULL ) return ERROR_ABRIENDO; + + ch=fgetc(fichero); //Lee el primer caracter + while (ch!=EOF) { //Lee hasta fin de fichero + + if (ch=='*') //Linea con comentario + while (ch!=EOL && ch!=EOF) ch=fgetc(fichero); + + if (ch=='') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + secuencia_activa = numero; + } + + if (ch=='&' && secuencia_activa == Sec_st) { //Clculos del boton estatico + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Left = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Up = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Right =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + if(ch == '-' || ch == '-') signo = 1; + ch=fgetc(fichero); + } + if ( signo==1 ) + Bot_Static.Down =numero * -1; + else + Bot_Static.Down =numero; + signo = 0; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cdf =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cb1 =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Cb2 =numero; + + numero=0; Relleno = 1; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; else + if(ch == '-' || ch == '-') Relleno = 0; + ch=fgetc(fichero); + } + Bot_Static.Ab =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + Bot_Static.Pb =numero; + Imprime_Boton(Relleno, Bot_Static); + } + if (ch=='|' && secuencia_activa == Sec_st) { //Clculos del texto + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + x = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + y = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fuente = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + size = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + orientacion = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + color = numero; + + buffer[0] = '\0'; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',' && numero<150 ) { + ch=fgetc(fichero); + if(ch!=',') { buffer[numero] = ch; numero++; } + } + + buffer[numero] = '\0'; + setcolor(color); + /* select the registered font */ + settextstyle( fuente, orientacion, size); + outtextxy(x, y, buffer); + + + } + + + if (ch!=EOF) ch=fgetc(fichero); + } + + if( fclose(fichero) != 0 ) return ERROR_CERRANDO; + return OK; +} + +void Imprime_Secuencia(int Sec_num){ + int psec = P_Sec(Sec_num-1); + for(int i=0; in_Botones_Secuencia[Sec_num-1] ) return; + + Boton--; + + if( Color < 0 ) + { + Imprime_Boton( 0, Botones[psec+Boton] ); + return; + } + +if ( Botones[psec+Boton].Down < 0 ) + { + + setlinestyle(0, 1, NORM_WIDTH); + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + for ( puntos[0] = 0; puntos[0] < Botones[psec+Boton].Ab; puntos[0]++ ) + circle( Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right - puntos[0]); + + if( Botones[psec+Boton].Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Botones[psec+Boton].Cdf); + circle( Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right); + } + + } else { + + puntos[0] = Botones[psec+Boton].Left; puntos[1] = Botones[psec+Boton].Up; + puntos[2] = Botones[psec+Boton].Right; puntos[3] = Botones[psec+Boton].Up; + puntos[4] = Botones[psec+Boton].Right; puntos[5] = Botones[psec+Boton].Down; + puntos[6] = (Botones[psec+Boton].Right-Botones[psec+Boton].Ab); puntos[7] = (Botones[psec+Boton].Down-Botones[psec+Boton].Ab); + puntos[8] = (Botones[psec+Boton].Right-Botones[psec+Boton].Ab); puntos[9] = (Botones[psec+Boton].Up+Botones[psec+Boton].Ab); + puntos[10] = (Botones[psec+Boton].Left+Botones[psec+Boton].Ab); puntos[11] = (Botones[psec+Boton].Up+Botones[psec+Boton].Ab); + puntos[12] = Botones[psec+Boton].Left; puntos[13] = Botones[psec+Boton].Up; + + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + puntos[0] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[1] = Botones[psec+Boton].Up+Botones[psec+Boton].Ab; + puntos[2] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[3] = Botones[psec+Boton].Down-Botones[psec+Boton].Ab; + puntos[4] = Botones[psec+Boton].Right-Botones[psec+Boton].Ab; puntos[5] = Botones[psec+Boton].Down-Botones[psec+Boton].Ab; + puntos[6] = Botones[psec+Boton].Right; puntos[7] = Botones[psec+Boton].Down; + puntos[8] = Botones[psec+Boton].Left; puntos[9] = Botones[psec+Boton].Down; + puntos[10] = Botones[psec+Boton].Left; puntos[11] = Botones[psec+Boton].Up; + puntos[12] = Botones[psec+Boton].Left+Botones[psec+Boton].Ab; puntos[13] = Botones[psec+Boton].Up+Botones[psec+Boton].Ab; + + setcolor(Color); + setfillstyle(SOLID_FILL, Color); + setlinestyle(0, 1, NORM_WIDTH); + fillpoly(7, puntos); + + if( Botones[psec+Boton].Ab >= 2 ) { + setcolor( NEGRO ); + setfillstyle(EMPTY_FILL, Botones[psec+Boton].Cdf); + rectangle(Botones[psec+Boton].Left, Botones[psec+Boton].Up, Botones[psec+Boton].Right, Botones[psec+Boton].Down); + } +} + +} + + +int Comprueba_Secuencia(int Sec_num){ + + char key, key2=0; + int i, Pulso = 0; + int psec = P_Sec(Sec_num-1); + + + + if ( Espera_Tecla_o_Raton() == 0 ) { + + if ( (key = getch())==0) key2 = getch(); + for(i=0; i= Botones[psec+i].Left) && (x_raton <= Botones[psec+i].Right) && + (y_raton >= Botones[psec+i].Up) && (y_raton <= Botones[psec+i].Down) ) { + + Pulso = i + 1; + Push = ON; + Imprime_Boton_i(Botones[psec+Pulso-1]); + Anclar_Raton(); + if( Push == ON && True_Push == ON ) Deprime_Image(Botones[psec+Pulso-1]); + Push = OFF; + Imprime_Boton(0, Botones[psec+Pulso-1]); + return Pulso; + } + + return (0); +} + + +void Anclar_Raton(void){ + + union REGS io; + io.x.ax = 3; + do { + int86(0x33, &io, &io); + } while( (io.x.bx & 1)==1 || ((io.x.bx >> 1) & 1)==1); +} + + +int Espera_TeclaRaton(void){ + +// inicializa_raton_grafico(0, 0, 624, 464); +// char boton_izq, boton_der; + char Que; + activa_raton(); + + union REGS io; + io.x.ax = 3; + + do{ + int86(0x33, &io, &io); // lee posicin y estados del botn +// boton_izq = io.x.bx & 1; +// boton_der = (io.x.bx >> 1) & 1; + x_raton = io.x.cx; + y_raton = io.x.dx; + + }while( (io.x.bx & 1) == 0 && ((io.x.bx >> 1) & 1) == 0 && !MB_TeclaPulsada() ); + + + + + ///////////////////////////////////////// + // RETURN Derecho Izquierdo // + // // + // 0 0 0 // + // 1 1 0 // + // 2 0 1 // + // 3 1 1 // + // // + ///////////////////////////////////////// + + + if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==0 ) Que = 0; + if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==0 ) Que = 1; + if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==1 ) Que = 2; + if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==1 ) Que = 3; + + desactiva_raton(); + return Que; +} + + + + +void inicializa_raton_grafico(int x1, int y1, int x2, int y2) +{ + +int px = x_raton, py = y_raton; + + struct SREGS seg; + union REGS ent, sal; + long dir; + + ent.x.ax = 0; + int86(0x33, &ent, &sal); /* averigua si hay ratn conectado */ + + raton = sal.x.ax; /* indica a la variable global el estado + del raton */ + + if(raton!=0) { + + + ent.x.ax = 15; + ent.x.cx = 5; + ent.x.dx = 11; + int86(0x33, &ent, &sal); /* fija la razn mickey/pixel */ + + ent.x.ax = 7; + ent.x.cx = x1; + ent.x.dx = x2; + int86(0x33, &ent, &sal); /* fija la posicin mx. y mn. horizontal */ + + ent.x.ax = 8; + ent.x.cx = y1; + ent.x.dx = y2; + int86(0x33, &ent, &sal); /* fija la posicin mx. y mn. vertical */ + + if ( PunteroRaton == 100 ) { + if ( Carga_Puntero_Animado() ) { PunteroRaton = 1; Carga_Puntero(); } +} else Carga_Puntero(); + + if( PunteroRaton != 100 && PunteroRaton != 0) { + dir = (long)dir_raton; + ent.x.ax = 9; + ent.x.bx = 0; + ent.x.cx = 0; + ent.x.dx = (int) dir; + seg.es = (int) (dir >> 16); + int86x(0x33, &ent, &sal, &seg); /* asigna un cursor diferente */ + } + + ent.x.ax = 4; + ent.x.cx = px; + x_raton=ent.x.cx >> 1; + ent.x.dx = py; + y_raton=ent.x.dx; + int86(0x33, &ent, &sal); /* fija la posicin del ratn */ + + ent.x.ax = 1; + +if( PunteroRaton != 100 ) + int86(0x33, &ent, &sal); /* muestra el puntero del ratn */ + + desactiva_raton(); + + } +} + +void activa_raton(void) +{ + union REGS ent; + + ent.x.ax = 1; + int86(0x33, &ent, &ent); +} + +void desactiva_raton(void) +{ + union REGS ent; + + ent.x.ax = 2; + int86(0x33, &ent, &ent); +} + + + + + +void Initialize(int GraphDriver, int GraphMode) +{ + int errorcode; + +/* + if( (errorcode = registerbgifont(SMALL_FONT)) < 0 ) + ErrorOccurred(errorcode); +*/ + + /* report any registration errors */ +/* if ( (errorcode = registerbgidriver(EGAVGA_driver) ) < 0) + ErrorOccurred(errorcode); +*/ + /* initialize graphics and local variables */ + initgraph( &GraphDriver, &GraphMode, "" ); + + /* read result of initialization */ + errorcode = graphresult(); + if (errorcode != grOk) /* an error occurred */ + ErrorOccurred(errorcode); + + +} + +void ErrorOccurred(int errorcode) { + printf("Graphics error: %s\n", grapherrormsg(errorcode)); + printf("Press any key to halt:"); + getch(); + exit(1); /* terminate with an error code */ +} + +void Libera_Memoria(void){ + if ( memoria_asignada == 1 ) { // Libera antiguos datos + free(n_Botones_Secuencia); + farfree(Botones); + memoria_asignada = 0; + } +} + + +int Espera_Tecla_o_Raton(void){ + +// inicializa_raton_grafico(0, 0, 624, 464); +char Vez_Raton; int x, y; +char boton_izq=0, boton_der=0; +char Que; +// static char vez = 0; + +Vez_Raton = 0; + +union REGS io; + +if ( PunteroRaton!=100 ){ return Espera_TeclaRaton(); } + +if(raton!=0) { + desactiva_raton(); + io.x.ax = 3; +} + + do{ + if(raton!=0) { + int86(0x33, &io, &io); // lee posicin y estados del botn + boton_izq = io.x.bx & 1; + boton_der = (io.x.bx >> 1) & 1; + if ( x_raton != io.x.cx || y_raton != io.x.dx ) { + if(Vez_Raton==0) Vez_Raton = 1; else + putimage(x_raton, y_raton, Pantalla, COPY_PUT); + x_raton = io.x.cx; + y_raton = io.x.dx; + getimage(x_raton, y_raton, x_raton+21, y_raton+21, Pantalla); + + if( Vez_Raton ==14 ) { Vez_Raton = 1; } + if( Vez_Raton ==13 ) { Vez_Raton =14; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton ==12 ) { Vez_Raton =13; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton ==11 ) { Vez_Raton =12; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton ==10 ) { Vez_Raton =11; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 9 ) { Vez_Raton =10; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 8 ) { Vez_Raton = 9; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 7 ) { Vez_Raton = 8; // putimage(x_raton, y_raton, P_Raton4, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton4[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton4[x+y*20]); + } else + if( Vez_Raton == 6 ) { Vez_Raton = 7; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 5 ) { Vez_Raton = 6; // putimage(x_raton, y_raton, P_Raton3, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton3[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton3[x+y*20]); + } else + if( Vez_Raton == 4 ) { Vez_Raton = 5; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton == 3 ) { Vez_Raton = 4; // putimage(x_raton, y_raton, P_Raton2, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton2[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton2[x+y*20]); + } else + if( Vez_Raton == 2 ) { Vez_Raton = 3; // putimage(x_raton, y_raton, P_Raton1, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton1[x+y*20] != 253) putpixel(x_raton + x, y_raton + y, P_Raton1[x+y*20]); + + } + if( Vez_Raton == 1 ) { Vez_Raton = 2; // putimage(x_raton, y_raton, P_Raton1, 0); + for(y=0; y<20; y++) + for(x=0; x<20; x++) + if( P_Raton1[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton1[x+y*20]); + + } + +/* + if( Vez_Raton == 1 ) { Vez_Raton = 1; + + for(y=0; y<=20; y++) + for(x=0; x<=20; x++) + if( P_Raton1[x+y*20] != 253 ) putpixel(x_raton + x, y_raton + y, P_Raton1[4+x+y*20]); + putimage(x_raton, y_raton, P_Raton1, 0); + + } +*/ + } + } + }while( boton_izq == 0 && boton_der == 0 && !MB_TeclaPulsada() ); + +if( raton!=0 ) + putimage(x_raton, y_raton, Pantalla, COPY_PUT); + + + + ///////////////////////////////////////// + // RETURN Derecho Izquierdo // + // // + // 0 0 0 // + // 1 1 0 // + // 2 0 1 // + // 3 1 1 // + // // + ///////////////////////////////////////// + + + if ( boton_der==0 && boton_izq==0 ) Que = 0; + if ( boton_der==1 && boton_izq==0 ) Que = 1; + if ( boton_der==0 && boton_izq==1 ) Que = 2; + if ( boton_der==1 && boton_izq==1 ) Que = 3; +/* +if(raton!=0) + activa_raton(); +*/ + return Que; +} + + +unsigned long JD_imagesize(int left, int top, int right, int bottom) { + + unsigned long X_width, Y_width; + + X_width= ( (left > right) ? (left - right + 1) : ( right - left + 1) ); + Y_width= ( ( top > bottom) ? ( top - bottom + 1) : (bottom - top + 1) ); + + return (X_width * Y_width + 4); + +}; + + +void Libera_Raton_Animado(void){ + + +if ( PunteroRaton == 100 ) { + free(P_Raton1); + free(P_Raton2); + free(P_Raton3); + free(P_Raton4); + free(Pantalla); +} + +} + +void Carga_Puntero(void){ + + switch( PunteroRaton ) { + + case 0: + break; + case 1: + dir_raton [ 0] = 0x007F; /* 1 1 1 1 1 1 1*/ + dir_raton [ 1] = 0x00FF; /* 1 1 1 1 1 1 1 1*/ + dir_raton [ 2] = 0x01FF; /* 1 1 1 1 1 1 1 1 1*/ + dir_raton [ 3] = 0x01FF; /* 1 1 1 1 1 1 1 1 1*/ + dir_raton [ 4] = 0x00FF; /* 1 1 1 1 1 1 1 1*/ + dir_raton [ 5] = 0x007F; /* 1 1 1 1 1 1 1*/ + dir_raton [ 6] = 0x18FF; /* 1 1 1 1 1 1 1 1 1 1*/ + + dir_raton [ 7] = 0x800F; /*1 1 1 1 1*/ + dir_raton [ 8] = 0x8083; /*1 1 1*/ + dir_raton [ 9] = 0x8001; /*1 1*/ + dir_raton [10] = 0xF810; /*1 1 1 1 1 1 1*/ + dir_raton [11] = 0x8810; /*1 1 1 1*/ + dir_raton [12] = 0x8811; /*1 1 1 1*/ + dir_raton [13] = 0x8003; /*1 1 1*/ + dir_raton [14] = 0x8007; /*1 1 1 1*/ + dir_raton [15] = 0x800F; /*1 1 1 1 1*/ + + dir_raton [16] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [17] = 0x7E00; /*0 0 0 0 0 0 0 0 0 0*/ + dir_raton [18] = 0x7C00; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [19] = 0x7C00; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [20] = 0x7E00; /*0 0 0 0 0 0 0 0 0 0*/ + dir_raton [21] = 0x6700; /*0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [22] = 0x0200; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + + dir_raton [23] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [24] = 0x3E70; /*0 0 0 0 0 0 0 0*/ + dir_raton [25] = 0x0248; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [26] = 0x0244; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [27] = 0x0242; /*0 0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [28] = 0x2244; /*0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [29] = 0x2248; /*0 0 0 0 0 0 0 0 0 0 0 0*/ + dir_raton [30] = 0x3E70; /*0 0 0 0 0 0 0 0*/ + dir_raton [31] = 0x0000; /*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*/ + }; + + +}; + +int Carga_Puntero_Animado(void) { + + +// char *P_Raton; +if( ((P_Raton1 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton2 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton3 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) || + ((P_Raton4 = (unsigned char *)malloc( ( 22 * 22 ) ))==NULL) ) { + return 1; + } + +if ( (Pantalla = malloc( JD_imagesize(0, 0, 22, 22) )) == NULL ) + return 1; +/* +P_Raton = P_Raton1; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton2; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton3; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; +*P_Raton++ = BLANCO ; *P_Raton++ = NEGRO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; + +P_Raton = P_Raton4; +*P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = BLANCO ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = AZUL ; *P_Raton++ = AZUL ; +*P_Raton++ = AZUL ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; *P_Raton++ = GRIS_CLARO; +*P_Raton++ = GRIS_CLARO; *P_Raton++ = UNKNOW ; *P_Raton++ = UNKNOW ; *P_Raton++ = GRIS_CLARO; +*/ +return 0; +} + + +/// int MB_TeclaPulsada(void) +/* Esta funcin mira si se ha pulsado una tecla pero SIN llamadas a la BIOS, + de forma que no se inhabilitan las interrupciones en cada llamada, cosa + que bajara mucho la calidad de reproduccin con el altavoz interno. */ +/// { +/// return ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ); +/// } \ No newline at end of file diff --git a/MAKE_BOT/MAKE_BOT.H b/MAKE_BOT/MAKE_BOT.H new file mode 100644 index 0000000..f1d7d19 --- /dev/null +++ b/MAKE_BOT/MAKE_BOT.H @@ -0,0 +1,163 @@ +// +// Errores devueltos por las Funciones +// + +#define OK 1 +#define SIN_MEMORIA 5 +#define ERROR_ABRIENDO 6 +#define ERROR_CERRANDO 7 + +#define ON 1 +#define OFF 0 + +#define EOL 10 // Fin de linea + +#define MB_TeclaPulsada() ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ) +// +// Funciones propias de MAKE_BOTON +// + + // + // Carga los botones del fichero *f_datos, devolviendo los + // errores indicados en #define xxxxx X + // + int carga_botones(char *f_datos); + + // + // Despliega los datos que fueron cargados. + // + // + void despliega_datos(void); + + // + // Imprime los botones estaticos de la secuencia Sec_st, en el + // fichero file. + // + int Imprime_Estaticos(int Sec_st, char *file); + + // + // Imprime los botones dinmicos de la secuencia Sec_num. + // + // + void Imprime_Secuencia(int Sec_num); + + // + // + // Imprime un borde completo de color Color sobre el boton Boton, + // de la secuencia nmero Sec_num. + // + // NOTA: + // Si color es negativo se imprimiran los bordes normales. + // + // + void Imprime_Bordes(int Sec_num, int Boton, int Color); + + // + // Comprueba la pulsacin de los botones de la secuencia Sec_num + // + // Devuelve el nmero de boton pulsado, 0 si no se pulso ninguno + // y deja en el buffer las teclas pulsadas si no corresponden con + // con las teclas asignadas a los botones. + // + int Comprueba_Secuencia(int Sec_num); + + // + // Libera la memoria que ha sido asignada por Make_Boton. + // + // NOTA: + // DESPUES DE LIBERAR TODA LA MEMORIA DE M_B, NO SE DEBE + // UTILIZAR NINGUNA FUNCION SIN RECARGAR PRIMERO LOS BOTONES DE + // DE UN ARCHIVO CON ESTOS... + // + // FUNCION EXTRAIDA PARA USO COMUN, ESPECIALMENTE POR CD_out + // + void Libera_Memoria(void); + + // + // + // Si True_Push se pone a ON, cuando se pulse un boton se hundira + // realmente, pero solo si hay suficiente memoria. + // + // + extern char True_Push; + +// +// Funciones para el control de la Pantalla +// + // + // + // Sirve para averiguar el tamao necesitado por GetImage para + // obtener una imagen 256c, para los BGI no compatibles KERNEL. + // + // + unsigned long JD_imagesize(int left, int top, int right, int bottom); + + // + // + // Igual a InitGraph, pero realiza un mayor numero de comproba_ + // ciones, saliendo si ocurre algun error y mostrandolo... + // + // + void Initialize(int GraphDriver, int GraphMode); // Inicializa el Modo Grfico + +// +// Funciones para el control del Raton +// + + // + // + // Muestra el cursor del Raton. - No sirve con el raton animado + // + // + void activa_raton(void); + + // + // + // Desactiva el cursor del Raton. No sirve con el raton animado + // + // + void desactiva_raton(void); + + // + // + // Regresa con una pulsacin de tecla o la posicin en la cual + // se pulso el raton. + // + // + int Espera_Tecla_o_Raton(void); // <-> + + // + // + // Sostiene el raton hasta que se suelte el boton presionado... + // + // + void Anclar_Raton(void); + + // + // + // Libera la memoria asignada al Raton Animado. + // + // + void Libera_Raton_Animado(void); + + // + // + // Inicializa el Raton en el modo Grfico... + // + // x1, y1, x2, y2. Son los topes del RATON + // + // + // + // + void inicializa_raton_grafico(int x1, int y1, // Inicializa el Raton + int x2, int y2); // devolviendo raton = 1 + + + + extern char Push; + extern char raton; // Indica si hay un Raton = 1 + extern char PunteroRaton; // Se modifica el puntero ? + extern int x_raton, y_raton; // Tras Espera_Tecla_o_Raton(); devuelve +// extern int boton_izq, boton_der; // las coordenadas y botones pulsados... + + extern unsigned char BLANCO, GRIS_CLARO, NEGRO, UNKNOW, AZUL; diff --git a/MAKE_BOT/MB_2_C.CPP b/MAKE_BOT/MB_2_C.CPP new file mode 100644 index 0000000..ff52265 --- /dev/null +++ b/MAKE_BOT/MB_2_C.CPP @@ -0,0 +1,493 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OK 1 +#define SIN_MEMORIA 5 +#define ERROR_ABRIENDO 6 +#define ERROR_CERRANDO 7 + +#define EOL 10 // Fin de linea + +int Secuencias; +int *n_Botones_Secuencia; +int memoria_asignada = 0, vez = 0; + +struct Make_Boton { + int Left, Up, Right, Down; + int Cdf, Cb1, Cb2; + int Ab, Pb; + int Isc, Sc; +}; + +struct Make_Boton far *Botones; // Puntero a estructura +struct Make_Boton Bot_Static; + +int Analiza_Fichero_Dinamicos(char *f_datos); +int Analiza_Fichero_Estaticos(char *f_datos); + +void ErrorOccurred(int errorcode); + +int lee_objeto(FILE *); // Lee el objeto del disco + +FILE *MB_out; + +void main(int argc, char *argv[] ) { + + char Buffer[80]; int len; + char *ptr = argv[2]; + + if ( argc != 3 ) { + + printf("\n"); + printf("FALTAN PARAMETROS\n"); + printf("\n"); + printf(" MB2SRC [Fichero_Fuente] [Destino_CPP.CPP]\n"); + printf("\n"); + + return; + } + + /* open a file for update */ + if( (MB_out = fopen(argv[2], "w")) == NULL ) { + printf("\nError Abriendo Archivo destino"); + return; + } + fprintf( MB_out, "/***************************************************************/\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/* Conversin de fuentes de MAKE BOTON en ASCII a fuentes */\n"); + fprintf( MB_out, "/* para CPP, que pueden ser compilados junto al programa. */\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/***************************************************************/\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/* MAKE BOTON es un programa realizado por Jos David Guilln */\n"); + fprintf( MB_out, "/* MB a CPP es una utilidad complementaria a Make Boton por */\n"); + fprintf( MB_out, "/* Jos David Guilln... */\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/***************************************************************/\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/* GRACIAS POR UTILIZAR MI SOFTWARE... */\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/* JOS DAVID GUILLN (c) 1995 */\n"); + fprintf( MB_out, "/* */\n"); + fprintf( MB_out, "/***************************************************************/\n"); + fprintf( MB_out, "\n\n\n"); + fprintf( MB_out, "// Debe indicar el directorio exacto de la Cabecera de MAKE BOTON\n"); + fprintf( MB_out, "#include \"Make_bot.h\"\n"); + fprintf( MB_out, "#include \"stdlib.h\"\n"); + fprintf( MB_out, "#include \"alloc.h\"\n"); + fprintf( MB_out, "#include \"graphics.h\"\n"); + fprintf( MB_out, "\n\n\n"); + fprintf( MB_out, "extern int vez, memoria_asignada, Secuencias, *n_Botones_Secuencia;\n"); + fprintf( MB_out, " struct Make_Boton { int Up, Left, Down, Right; int Cdf, Cb1, Cb2; int Ab, Pb; int Isc, Sc; };\n"); + fprintf( MB_out, "extern struct Make_Boton far *Botones, Bot_Static;\n"); + + + + fprintf( MB_out, "\n\n\n"); + fprintf( MB_out, "extern void Libera_Memoria(void);"); + fprintf( MB_out, "extern void Imprime_Boton(int D_Bord, struct Make_Boton Bot_Imp);"); + fprintf( MB_out, "\n\n\n"); + fprintf( MB_out, "// Esta funcin debe ser llamada para la inicializacion de los\n"); + fprintf( MB_out, "// botones en lugar de CARGA_BOTONES(...). \n"); + + fprintf( MB_out, "// Para cargar los botones con parametro 0 y para imprimir \n"); + fprintf( MB_out, "// imprimir los estaticos con parametro [ n de secuencia ] \n"); + len = 0; + while( *ptr++ != NULL && *ptr != '.' ) len++; + strncpy( Buffer, argv[2], len+1 ); + Buffer[len+1] = '\0' ; + + fprintf( MB_out, "int Fichero_%s(char Dinamicos_Estaticos);\n\n", Buffer ); + fprintf( MB_out, "int Fichero_%s(char Dinamicos_Estaticos) {\n", Buffer ); + + fprintf( MB_out, "\n"); + + fprintf( MB_out, " switch(Dinamicos_Estaticos) {\n"); + fprintf( MB_out, "\n"); + fprintf( MB_out, " case 0:\n"); + if ( Analiza_Fichero_Dinamicos(argv[1]) != OK ) { printf( "ERROR ANALIZANDO FICHERO EN SECCION DINAMICOS..." ); return; }; + + if ( Analiza_Fichero_Estaticos(argv[1]) != OK ) { printf( "ERROR ANALIZANDO FICHERO EN SECCION ESTATICOS..." ); return; }; + fprintf( MB_out, " break;\n"); + fprintf( MB_out, " default:\n"); + fprintf( MB_out, " break;\n"); + fprintf( MB_out, " }\n"); + fprintf( MB_out, "}\n"); + + fclose(MB_out); + +} + +int Analiza_Fichero_Dinamicos(char *f_datos){ + FILE *fichero; + int error_lectura = OK; + + fprintf( MB_out, " if( vez == 0 ) {\n"); + fprintf( MB_out, " vez = 1;\n"); + fprintf( MB_out, " atexit( Libera_Memoria );\n"); + fprintf( MB_out, " }\n"); + fprintf( MB_out, " if ( memoria_asignada == 1 ) { \n"); + fprintf( MB_out, " free(n_Botones_Secuencia);\n"); + fprintf( MB_out, " farfree(Botones);\n"); + fprintf( MB_out, " memoria_asignada = 0;\n"); + fprintf( MB_out, " }\n"); + + if ( (fichero=fopen(f_datos,"r"))==NULL ) return ERROR_ABRIENDO; + + char ch/*, buffer[80]*/; + int signo,numero, temp_num, temp_b; + int inc_Botones = -1; + fprintf( MB_out, " int SiZe_BoToN = 0;\n"); + fprintf( MB_out, " if ( (Botones = (struct Make_Boton far *)farcalloc(1, sizeof( struct Make_Boton ) )) == NULL)\n"); + fprintf( MB_out, " return SIN_MEMORIA;\n"); + fprintf( MB_out, " memoria_asignada = 1;\n"); + fprintf( MB_out, "\n"); + + + ch=fgetc(fichero); //Lee el primer caracter + while (ch!=EOF) { //Lee hasta fin de fichero + if (ch=='*') //Linea con comentario + while (ch!=EOL && ch!=EOF) ch=fgetc(fichero); + + if (ch=='#') { //Numero de secuencias + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF) { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + fprintf( MB_out, " Secuencias = %d;\n", numero); + fprintf( MB_out, " if (( n_Botones_Secuencia = (int *) malloc( sizeof(int)*Secuencias ) ) == NULL) {\n"); + fprintf( MB_out, " printf(\"\\nNo Hay suficiente Memoria, ni para un Boton\\n\\n\");\n"); + fprintf( MB_out, " return SIN_MEMORIA;\n"); + fprintf( MB_out, " }\n"); + } + + if (ch=='!') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } + temp_num = numero; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero= (numero*10+ch-48); + ch=fgetc(fichero); + } +// fprintf( MB_out, " }\n"); + fprintf( MB_out, " n_Botones_Secuencia[%d - 1] = %d;\n", temp_num, numero); + fprintf( MB_out, " SiZe_BoToN += ( sizeof( struct Make_Boton ) * %d);\n", numero); + fprintf( MB_out, " if ( (Botones = (struct Make_Boton far *)farrealloc(Botones, SiZe_BoToN )) == NULL) {\n"); + fprintf( MB_out, " Secuencias = %d;\n", temp_num); + fprintf( MB_out, " return SIN_MEMORIA;\n"); + fprintf( MB_out, " }\n"); + fprintf( MB_out, " memoria_asignada = 1;\n"); + + } + if (ch=='$') { //Clculos del boton + inc_Botones++; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d].Left = %d; ", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, "Botones [%d].Up = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, "Botones [%d]. Right = %d;", inc_Botones, numero); +// Botones [inc_Botones]. Right =numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, "Botones [%d]. Down = %d;\n", inc_Botones, numero); + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Cdf = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Cb1 = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Cb2 = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Ab = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Pb = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Isc = %d;", inc_Botones, numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Botones [%d]. Sc = %d;\n", inc_Botones, numero); + + } + + if (ch!=EOF) ch=fgetc(fichero); + } + + + + if( fclose(fichero) != 0 ) return ERROR_CERRANDO; + +// despliega_datos(); + +// while (!kbhit()); // Espera a que se pulse una tecla + + return error_lectura; +} + + +// +// +int Analiza_Fichero_Estaticos(char *f_datos){ + + char ch, Relleno = 1; + int x, y, fuente, size, orientacion, color; + char buffer[160]; + int signo,numero, temp_num, temp_b; + int secuencia_activa=-1; + + FILE* fichero; // Fichero con datos del obj. + + if ( (fichero=fopen(f_datos,"r"))==NULL ) return ERROR_ABRIENDO; + + ch=fgetc(fichero); //Lee el primer caracter + while (ch!=EOF) { //Lee hasta fin de fichero + + if (ch=='*') //Linea con comentario + while (ch!=EOL && ch!=EOF) ch=fgetc(fichero); + + if (ch=='') { //Numero de Botones en la secuencia + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + secuencia_activa = numero; + fprintf( MB_out, " break;\n"); + fprintf( MB_out, " case %d:\n", secuencia_activa); + } + + if (ch=='&' /*&& secuencia_activa == Sec_st*/) { //Clculos del boton estatico + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Left = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Up = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Right = %d;", numero); + + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Down = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Cdf = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Cb1 = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Cb2 = %d;", numero); + + numero=0; Relleno = 1; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; else + if(ch == '-' || ch == '-') Relleno = 0; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Ab = %d;", numero); + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fprintf( MB_out, " Bot_Static.Pb = %d;\n", numero); + fprintf( MB_out, " Imprime_Boton(%d, Bot_Static);\n", Relleno); + + } + if (ch=='|' /*&& secuencia_activa == Sec_st*/) { //Clculos del texto + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + x = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + y = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + fuente = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + size = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + orientacion = numero; + + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',') { + if (ch>='0' && ch<='9') numero=numero*10+ch-48; + ch=fgetc(fichero); + } + color = numero; + + buffer[0] = '\0'; + numero=0; + ch=fgetc(fichero); + while (ch!=EOL && ch!=EOF && ch!=',' && numero<150 ) { + ch=fgetc(fichero); + if(ch!=',') { buffer[numero] = ch; numero++; } + } + + buffer[numero] = '\0'; + fprintf( MB_out, " setcolor(%d);", color); + + /* select the registered font */ + fprintf( MB_out, " settextstyle( %d, %d, %d);", fuente, orientacion, size); + fprintf( MB_out, " outtextxy( %d, %d, \"%s\" );\n", x, y, buffer); + + + + } + + + if (ch!=EOF) ch=fgetc(fichero); + } + + if( fclose(fichero) != 0 ) return ERROR_CERRANDO; +// if( fclose(fichero) != 0 ) return ERROR_CERRANDO; + return OK; +} + +Red y asegrese de que \ No newline at end of file diff --git a/MAKE_BOT/MK_BOT.HLP b/MAKE_BOT/MK_BOT.HLP new file mode 100644 index 0000000..5eebe9c --- /dev/null +++ b/MAKE_BOT/MK_BOT.HLP @@ -0,0 +1,237 @@ +* +* Programa diseado, integramente, por: +* +* Jos David Guilln Dominguez +* J.D. FuTuRe ViSiOn +* +* c/ Pintor Garcia Ramos n5 2D +* Alcal de Guadaira ( Sevilla ) +* C.P. 41500 +* +* Compilador: Borlandc C++ 3.0 +* +* P.D. Este programa es FuenteWare, lo que quiere decir que para +* registrarse, ( y recibir cualquier actualizacin ), hay que +* enviar un Cdigo Fuente, elaborado en C, a la direccin adjunta. +* +* + +* +* +* Este es el fichero que contiene las definiciones para los botones, +* como se puede observar, el asterisco al principio de una linea, es un +* comentario. +* +* + +* +* Para ver el tamao de codigo real usado, vete a la linea, +* + +* +* #, simboliza el nmero de SECUENCIAS de BOTONES, que contiene el fichero +* +* ejemplo... Sea un programa con un Boton para SALIR y otro para AYUDA +* cuando se pulsa AYUDA, aparecen otros tres botones: ncias de botones +* detras indicamos: +* ![n de secuencia], [n de botones] +* + +* +* &, esta marca sirve para definir los botones en el siguiente orden: +* ( estticos ). +* $[Izquierda], [Arriba], [Derecha], [Abajo], [CDF], [Cb1], [Cb2], +* ,[Ab], [Pb] +* +* A diferencia de los dinmicos, los estaticos de dibujan a la vez que los +* dinmicos, pero no ocupan memoria. +* +* +* +* +* $, esta marca sirve para definir los botones en el siguiente orden: +* ( dinmicos ). +* $[Izquierda], [Arriba], [Derecha], [Abajo], [CDF], [Cb1], [Cb2], +* ,[Ab], [Pb], [IndexScanCode][ScanCode] +* +* +* CDF ---> Color de fondo. +* Cb1 ---> Color del borde 1. +* Cb2 ---> Color del borde 2. +* Ab ---> Ancho del borden. ( entre 2 y 10 "pixeles" ) +* Pb ---> Posicin del borde. Ver tabla 1.1 +* [ISC][SC] -> cdigo indice, cdigo de Scan. Ver tabla 1.3 +* +* +* Tabla 1.1 Tabla 1.2 +* +* B1 Esttico: es aquel que simplemente +* se dibuja. +* 1 2 +* Dinmico: es el que se dibuja y +* tiene asignada una tecla +* B2 que una vez pulsada, o +* pulsando sobre el boton, +* Tabla 1.3 har que el boton se +* deprima, devolviendo su +* Ejemplo: n de boton asignado. +* Ayuda (tecla 'H') 072000 ( segn orden en fichero ) +* Salir (tecla F1 ) 000059 +* +* +* El cdigo de tecla utilizado es el +* cdigo de caracteres ASCII, 32_90. +* En caso de ser una tecla especial, los 3 primeros dgitos deberan ser +* ceros. NO SE DEBEN OLVIDAR LOS CEROS PARA RELLENAR EL CODIGO. +* + + + +* +* Estos botones son estaticos, y solo sirven para adornar.... +* + +1 + +& 0, 0, 640, 480, 7, 56, 63, 2, 1 +& 10, 455, 630, 475, 7, 63, 56, 2, 1 + +2 + +& 330, 20, 630, 445, 7, 63, 56, 2, 1 +& 335, 25, 625, 440, 0, 56, 63, 2, 1 + + +* x y T.F. S. H. C. Texto. + +| 30, 20, 2, 6, 0, 63, Ayuda, +| 31, 21, 2, 6, 0, 0, Ayuda, + | 38, 21, 2, 6, 0, 0, -, + +| 130, 20, 2, 6, 0, 63, Acerca de, +| 131, 21, 2, 6, 0, 0, Acerca de, + | 138, 21, 2, 6, 0, 0, -, + +| 230, 20, 2, 6, 0, 63, Salir, +| 231, 21, 2, 6, 0, 0, Salir, + | 238, 21, 2, 6, 0, 0, -, + + +| 280, 20, 2, 20, 0, 63, Make_Boton, +| 281, 21, 2, 20, 0, 0, Make_Boton, + +| 320, 20, 2, 10, 0, 63, Jos David, +| 321, 21, 2, 10, 0, 0, Jos David, + +| 380, 20, 2, 8, 0, 63, JD FuTuRe ViSiOn, +| 381, 21, 2, 8, 0, 0, JD FuTuRe ViSiOn, + +4 + +* & 335, 25, 625, 440, 0, 56, 63, 2, 1, 2 + +|50, 350, 2, 6, 0, 63, Make_Boton es una producto, +|70, 350, 2, 6, 0, 63, FuenteWare lo que quiere , +|90, 350, 2, 6, 0, 63, decir que no es gratuito , +|110, 350, 2, 6, 0, 63, sino que para obtener el, +|130, 350, 2, 6, 0, 63, registro necesario para su, +|150, 350, 2, 6, 0, 63, utilizacin es necesario, +|170, 350, 2, 6, 0, 63, enviar un cdigo fuente, +|190, 350, 2, 6, 0, 63, realizado en C. CPP. ASM, +|210, 350, 2, 6, 0, 63, preferiblemente en CPP., + +|250, 350, 2, 5, 0, 63, Pulse una Tecla, + +3 + +* & 335, 25, 625, 440, 0, 56, 63, 2, 1, 2 + +|50, 350, 2, 6, 0, 63, Make_Boton, + +| 80, 350, 2, 6, 0, 63, Codificacin integra de JD, +| 100, 350, 2, 6, 0, 63, Jos David Guilln Dominguez, + +|130, 350, 2, 6, 0, 63, Pintor Garcia Ramos 5 2D, +|150, 350, 2, 6, 0, 63, Alcal de Guadaira (SEVILLA). +|170, 350, 2, 6, 0, 63, CP>41.500 Tlf. 561 - XX - XX, + + +|200, 350, 2, 5, 0, 63, Pulse una Tecla, + + + +* +* Acabo de definir dos Secuencias de botones. +* + +*#2 + +#1 + +* +* 1 secuencia con dos botones. +* + +!1,3 + +* +* Boton 1 +* + +$ 20, 20, 130, 60, 7, 56, 63, 1, 2, 65, 00 + +* +* Boton 2 +* + +$ 20, 120, 130, 160, 7, 56, 63, 1, 2, 67, 00 + +* +* Boton 3 +* + +$ 20, 220, 130, 260, 7, 56, 63, 1, 2, 83, 00 + +*$ 20, 20, 120, 50, 56, 7, 63, 56, 1, 2, 65, 00 + + + +* +* 2 secuencia con tres botones. +* + +!2, 3 + +* +* Boton 1 +* + +$20, 320, 420, 50, 56, 7, 63, 2, 1, 2, 072, 000 + +* +* Boton 2 +* + +$320, 120, 120, 450, 56, 7, 63, 2, 1, 2, 000, 059 + +* +* Boton 3 +* + +$20, 120, 120, 150, 56, 7, 63, 2, 1, 2, 000, 059 +); + Comodin--; if( *Comodin == ':' || *Comodin == '\\' ) strcat(Buffer, "*.*"); else + + if (findfirst(Buffer, &ftmp, atr) == 0 && strcmpi(Buffer, "*.*")!=0) { + strcat(Buffer, "\\*.*"); + } +} + +atr = FA_HIDDEN | FA_SYSTEM | FA_DIREC; + +if ( findfirst(Buffer, &ftmp, atr) != 0) { + textcolor(LIGHTGREEN); + cprintf("Fichero/sY-4#VAR/X11.{_2/LIB/SCORES/XBOMBSCO.{__xbombs/xbombscoresPK/F&G9$VAR/X11.{_2/LIB/X11.{_1/--LINUX-.---?K@_SK-AHr " UAй.:S'75M'qw&0QǴG$ʁ!tim=[|,g:%~; +R7ĿV8O"=L>.R~~_>S0/faϴuӎ>zANz?G";.SӱU/ 3R6=- m{ӿ]{'~6/D_'r0|I_<P?oo־U_m-/PK +qS+ ? +>VAR/X11.{_2/LIB/X11.{_1/F \ No newline at end of file diff --git a/MODS/DONTYOU.MOD b/MODS/DONTYOU.MOD new file mode 100644 index 0000000..4de19b6 Binary files /dev/null and b/MODS/DONTYOU.MOD differ diff --git a/MODS/EXAMPLE1.C b/MODS/EXAMPLE1.C new file mode 100644 index 0000000..730bf21 --- /dev/null +++ b/MODS/EXAMPLE1.C @@ -0,0 +1,24 @@ +#include +#include +#include "modplay.inc" + +unsigned int _stklen = 0x1000; /* set stack size to 4kB */ +unsigned int _heaplen = 0x0000; /* no heap required */ + +unsigned char Mod_File[128]; +unsigned char *DOS_Shell="C:\\COMMAND.COM"; + +void main(int argc, char *argv[]) +{ + if (argc>1) { + strcpy(Mod_File, argv[1]); + Mod_Init(Detection,0,0,0); + Mod_Load(Mod_File); + if (Channels!=0) { + Mod_Play(1); + DOS_Shell=getenv("COMSPEC"); + if (spawnl(P_WAIT, DOS_Shell, NULL)!=-1) printf("\nReturned... Music output stopped.\n"); + } + } + else printf("\nPlease specify a modulefile on the commandline !\n"); +} diff --git a/MODS/EXAMPLE1.DSK b/MODS/EXAMPLE1.DSK new file mode 100644 index 0000000..d314e0c Binary files /dev/null and b/MODS/EXAMPLE1.DSK differ diff --git a/MODS/EXAMPLE1.EXE b/MODS/EXAMPLE1.EXE new file mode 100644 index 0000000..b0df3bd Binary files /dev/null and b/MODS/EXAMPLE1.EXE differ diff --git a/MODS/EXAMPLE1.PRJ b/MODS/EXAMPLE1.PRJ new file mode 100644 index 0000000..28730c3 Binary files /dev/null and b/MODS/EXAMPLE1.PRJ differ diff --git a/MODS/EXAMPLE2.C b/MODS/EXAMPLE2.C new file mode 100644 index 0000000..5ec7458 --- /dev/null +++ b/MODS/EXAMPLE2.C @@ -0,0 +1,100 @@ +#include +#include +#include +#include "modplay.inc" + +unsigned int _stklen = 0x1000; /* set stack size to 4kB */ +unsigned int _heaplen = 0x0000; /* no heap required */ + +unsigned char Key, Main_Volume; +unsigned int Cursor_Shape; + +void Init_Cursor(void) +{ + asm { + mov ah,3 + xor bh,bh + int 10h + mov [Cursor_Shape],cx + mov ah,1 + mov cx,2020h + int 10h + } +} + +void Restore_Cursor(void) +{ + asm { + mov ah,1 + mov cx,[Cursor_Shape] + int 10h + } +} + +void Update_Screen(void) +{ + unsigned int i,j; + unsigned char Bar[32]; + unsigned int SongPos; + + gotoxy(1,7); + Mod_Peak(); + for(i=0; i1) for(j=0; j<(Peak[i]>>1); j++) Bar[j]=''; + gotoxy(2,4+i); cprintf("%s", Bar); + } + SongPos=Mod_Position(); + gotoxy(3,6+Channels); cprintf("Playing pattern #%d, line #%d ", SongPos>>8, SongPos&0x00ff); + gotoxy(62,wherey()); cprintf("Main volume: %3d%%", div(Main_Volume*100,64)); +} + +void main(void) +{ + Mod_Init(Detection,0,0,0); + if (Soundcard!=0) { + Mod_Load("DONTYOU.MOD"); + if (Channels!=0) { + Init_Cursor(); + Main_Volume=58; + Mod_Volume(Main_Volume); + Mod_Play(0); + textcolor(WHITE); textbackground(BLACK); + clrscr(); + textbackground(BLUE); gotoxy(1,1); clreol(); + gotoxy(22,1); cprintf("SOUND WIZARDS MODULE PLAYER 'C' DEMO"); + gotoxy(1,6+Channels); clreol(); + textbackground(BLACK); + gotoxy(36,1+Channels); cprintf("Press up,down: to adjust volume "); + gotoxy(36,2+Channels); cprintf(" left,right: to change position"); + gotoxy(36,3+Channels); cprintf("or escape to quit this little program......"); + textbackground(BLUE); + do { + Update_Screen(); + Key=' '; + if (kbhit()) Key=getch(); + if (Key==0) { /* only allow function keys */ + Key=getch(); + switch(Key) { + case 0x48: if (Main_Volume<64) { + Main_Volume+=2; + Mod_Volume(Main_Volume); + } + break; + case 0x50: if (Main_Volume>0) { + Main_Volume-=2; + Mod_Volume(Main_Volume); + } + break; + case 0x4d: Mod_Forward(); + break; + case 0x4b: Mod_Rewind(); + break; + } + } + } while((Mod_Status()!=0) && (Key!=27)); + gotoxy(1,9+Channels); + Restore_Cursor(); + } else printf("\nCould not load song DONTYOU.MOD...\n"); + } else printf("\nCould not initialize hardware..."); +} diff --git a/MODS/EXAMPLE2.DSK b/MODS/EXAMPLE2.DSK new file mode 100644 index 0000000..f90d1e6 Binary files /dev/null and b/MODS/EXAMPLE2.DSK differ diff --git a/MODS/EXAMPLE2.EXE b/MODS/EXAMPLE2.EXE new file mode 100644 index 0000000..e546c1f Binary files /dev/null and b/MODS/EXAMPLE2.EXE differ diff --git a/MODS/EXAMPLE2.PRJ b/MODS/EXAMPLE2.PRJ new file mode 100644 index 0000000..0980272 Binary files /dev/null and b/MODS/EXAMPLE2.PRJ differ diff --git a/MODS/MODPLAY.INC b/MODS/MODPLAY.INC new file mode 100644 index 0000000..9798bb3 --- /dev/null +++ b/MODS/MODPLAY.INC @@ -0,0 +1,185 @@ +/* ķ */ +/* SOUND WIZARDS MODULE PLAYER V1.3 BY LORD EXCESS */ +/* Ľ */ + +#include + +#define Detection 0 +#define SoundBlaster 1 +#define SoundBlaster_Pro 2 +#define Gravis_UltraSound 3 + +unsigned int Soundcard, Channels; +void *Mod_Driver; +unsigned char Peak[8]; + +extern void far Detect_Hardware(void); +extern void far Driver_SB(void); +extern void far Driver_SBP(void); +extern void far Driver_GUS(void); + +void Mod_Close(void) +{ + asm { + mov bx,1 + call DWORD PTR [Mod_Driver] + } +} + +void Mod_Init(unsigned int Driver, unsigned int Port, unsigned char IRQ, unsigned char DMA) +{ + asm { + mov ax,[Driver] + or ax,ax + jz l_1 + cmp ax,Gravis_UltraSound + ja l_Error + mov cl,BYTE PTR [IRQ] + mov ch,BYTE PTR [DMA] + mov dx,[Port] + jmp l_2 + } +l_1: + Detect_Hardware(); + asm { + or ax,ax + jz l_Error + cmp ax,Gravis_UltraSound + ja l_Error + } +l_2: + asm { + mov [Soundcard],ax + mov WORD PTR [Mod_Driver],0 + cmp ax,SoundBlaster + jnz l_3 + mov WORD PTR [Mod_Driver+2],SEG Driver_SB + jmp l_Test + } +l_3: + asm { + cmp ax,SoundBlaster_Pro + jnz l_4 + mov WORD PTR [Mod_Driver+2],SEG Driver_SBP + jmp l_Test + } +l_4: + asm { + mov WORD PTR [Mod_Driver+2],SEG Driver_GUS + } +l_Test: + asm { + xor bx,bx + call DWORD PTR [Mod_Driver] + or ax,ax + jz l_Error + } + if (atexit(Mod_Close)) { + Mod_Close(); +l_Error: + asm { + mov [Soundcard],0 + } + } +} + +void Mod_Load(char *File_Name) +{ + if (Soundcard) asm { + mov bx,2 + mov dx,WORD PTR [File_Name] + call DWORD PTR [Mod_Driver] + mov [Channels],ax + } + else Channels=0; +} + +void Mod_Play(unsigned int Looping) +{ + if (Soundcard) asm { + mov bx,3 + mov ax,[Looping] + call DWORD PTR [Mod_Driver] + } +} + +void Mod_Stop(void) +{ + if (Soundcard) asm { + mov bx,4 + call DWORD PTR [Mod_Driver] + } +} + +void Mod_Volume(unsigned char Volume) +{ + if (Soundcard) asm { + mov bx,5 + mov al,[Volume] + call DWORD PTR [Mod_Driver] + } +} + +unsigned int Mod_Status(void) +{ + if (Soundcard) { + asm { + mov bx,6 + call DWORD PTR [Mod_Driver] + } + return(_AX); + } + else return(0); +} + +unsigned int Mod_Position(void) +{ + if (Soundcard) { + asm { + mov bx,7 + xor al,al + call DWORD PTR [Mod_Driver] + } + return(_AX); + } + else return(0); +} + +void Mod_Rewind(void) +{ + if (Soundcard) asm { + mov bx,7 + mov al,-1 + call DWORD PTR [Mod_Driver] + } +} + +void Mod_Forward(void) +{ + if (Soundcard) asm { + mov bx,7 + mov al,1 + call DWORD PTR [Mod_Driver] + } +} + +void Mod_Peak(void) +{ + asm { + push es + mov ax,ds + mov es,ax + mov di,OFFSET Peak + } + if (Soundcard) asm { + mov bx,8 + call DWORD PTR [Mod_Driver] + } + else asm { + cld + mov cx,4 + xor ax,ax + rep stosw + } + asm pop es; +} diff --git a/MODS/MOD_DRV.OBJ b/MODS/MOD_DRV.OBJ new file mode 100644 index 0000000..84ff148 Binary files /dev/null and b/MODS/MOD_DRV.OBJ differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a388694 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +#LIBS + + +*~0,10* + +ToDo: wwtcf? + + +![screenshot](/LIBS.png "Screenshot") diff --git a/WAVPLAV/CIRCUITO.ASC b/WAVPLAV/CIRCUITO.ASC new file mode 100644 index 0000000..121a0b1 --- /dev/null +++ b/WAVPLAV/CIRCUITO.ASC @@ -0,0 +1,27 @@ + Puerto de impresora: + + seal pin + 20k 20k + D0 2 >İİ 0v (Tierra, pin 20) + 20k 10k + D1 3 >İĴ + 20k 10k + D2 4 >İĴ + 20k 10k + D3 5 >İĴ + 20k 10k + D4 6 >İĴ + 20k 10k + D5 7 >İĴ + 20k 10k + D6 8 >İĴ + 20k 10k + D7 9 >İĴ + 20k 10k 100nF + Ĵ> Al amplificador + + 10k 10nF + + Tierra 20 >> + 0v + diff --git a/WAVPLAV/DAC.CPP b/WAVPLAV/DAC.CPP new file mode 100644 index 0000000..986284b --- /dev/null +++ b/WAVPLAV/DAC.CPP @@ -0,0 +1,30 @@ +#include + +void InitDAC(void); +void LPT1DAC(unsigned char b); +void LPT2DAC(unsigned char b); + + +unsigned LPT1Addr = 0x378, + LPT2Addr = 0x278; + + +void InitDAC(void) +{ + unsigned *Addr; + + Addr = (unsigned *)MK_FP(0x40,0x8); + if (*Addr!=0) LPT1Addr = *Addr; + Addr = (unsigned *)MK_FP(0x40,0xA); + if (*Addr!=0) LPT2Addr = *Addr; +} + +void LPT1DAC(unsigned char b) +{ + outportb(LPT1Addr,b); +} + +void LPT2DAC(unsigned char b) +{ + outportb(LPT2Addr,b); +} diff --git a/WAVPLAV/DAC.H b/WAVPLAV/DAC.H new file mode 100644 index 0000000..ad86bca --- /dev/null +++ b/WAVPLAV/DAC.H @@ -0,0 +1,3 @@ +void InitDAC(void); +void LPT1DAC(unsigned char b); +void LPT2DAC(unsigned char b); diff --git a/WAVPLAV/DAC.OBJ b/WAVPLAV/DAC.OBJ new file mode 100644 index 0000000..a26dd43 Binary files /dev/null and b/WAVPLAV/DAC.OBJ differ diff --git a/WAVPLAV/LIB.BAT b/WAVPLAV/LIB.BAT new file mode 100644 index 0000000..2264f4e --- /dev/null +++ b/WAVPLAV/LIB.BAT @@ -0,0 +1,2 @@ +call setb +tlib %1 +dac +sb +speaker +vocplay diff --git a/WAVPLAV/P.BAT b/WAVPLAV/P.BAT new file mode 100644 index 0000000..9958f59 --- /dev/null +++ b/WAVPLAV/P.BAT @@ -0,0 +1 @@ +play 3ge89.wav %1 %2 diff --git a/WAVPLAV/PLAY.DSK b/WAVPLAV/PLAY.DSK new file mode 100644 index 0000000..97f4e6c Binary files /dev/null and b/WAVPLAV/PLAY.DSK differ diff --git a/WAVPLAV/PLAY.LIB b/WAVPLAV/PLAY.LIB new file mode 100644 index 0000000..0b9ee38 Binary files /dev/null and b/WAVPLAV/PLAY.LIB differ diff --git a/WAVPLAV/PLAY.PRJ b/WAVPLAV/PLAY.PRJ new file mode 100644 index 0000000..1b47ff8 Binary files /dev/null and b/WAVPLAV/PLAY.PRJ differ diff --git a/WAVPLAV/SB.CPP b/WAVPLAV/SB.CPP new file mode 100644 index 0000000..9fb8021 --- /dev/null +++ b/WAVPLAV/SB.CPP @@ -0,0 +1,57 @@ +#include + +int SBDetect(void); +void SBSendByte(unsigned char b); + +/* + Soporte de Sound Blaster +*/ + +unsigned BPORT = 0x210, + XPORT = 0x216, + WPORT = 0x21C, + RPORT = 0x21A, + APORT = 0x21E; + +char READY = 0xAA; + +int SBDetect(void) +{ + char Status,Ct; + + Status = 0; + while (Status!=READY && BPORT<0x270) + { + outportb(XPORT,1); + outportb(XPORT,0); + Ct = 0; + while (Status!=READY && Ct<100) + { + Status = inportb(RPORT); + Ct++; + }; + if (Status!=READY) + { + BPORT += 0x10; + XPORT += 0x10; + WPORT += 0x10; + RPORT += 0x10; + APORT += 0x10; + } + } + if (BPORT!=0x270) + { + while ((inport(WPORT) & 128) != 0); + outportb(WPORT,0xD1); + return(0); + } + else return(-1); +} + +void SBSendByte(unsigned char b) +{ + while ((inport(WPORT) & 128) != 0); + outportb(WPORT,0x10); + while ((inport(WPORT) & 128) != 0); + outportb(WPORT,b); +} diff --git a/WAVPLAV/SB.H b/WAVPLAV/SB.H new file mode 100644 index 0000000..f9c134c --- /dev/null +++ b/WAVPLAV/SB.H @@ -0,0 +1,2 @@ +int SBDetect(void); +void SBSendByte(unsigned char b); diff --git a/WAVPLAV/SB.OBJ b/WAVPLAV/SB.OBJ new file mode 100644 index 0000000..8f77f25 Binary files /dev/null and b/WAVPLAV/SB.OBJ differ diff --git a/WAVPLAV/SPEAKER.CPP b/WAVPLAV/SPEAKER.CPP new file mode 100644 index 0000000..1ab21ec --- /dev/null +++ b/WAVPLAV/SPEAKER.CPP @@ -0,0 +1,65 @@ +#include + +void InitSpeaker(void); +void CloseSpeaker(void); +void SpkSendByte(unsigned char b); + +/* + Rutinas de PWM para el altavoz interno del PC. +*/ + +unsigned char TablaSpeaker[256] = + {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3E,0x3E, + 0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E, + 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D, + 0x3D,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3B,0x3B,0x3B,0x3B,0x3B, + 0x3B,0x3B,0x3B,0x3B,0x3B,0x3A,0x3A,0x3A, + 0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x3A,0x39, + 0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39, + 0x39,0x38,0x38,0x38,0x38,0x38,0x38,0x38, + 0x38,0x37,0x37,0x37,0x37,0x37,0x36,0x36, + 0x36,0x36,0x35,0x35,0x35,0x35,0x34,0x34, + 0x34,0x33,0x33,0x32,0x32,0x31,0x31,0x30, + 0x30,0x2F,0x2E,0x2D,0x2C,0x2B,0x2A,0x29, + 0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21, + 0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19, + 0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11, + 0x11,0x10,0x10,0x0F,0x0F,0x0E,0x0E,0x0D, + 0x0D,0x0D,0x0C,0x0C,0x0C,0x0C,0x0B,0x0B, + 0x0B,0x0B,0x0A,0x0A,0x0A,0x0A,0x0A,0x09, + 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09, + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08,0x07,0x07,0x07,0x07, + 0x07,0x07,0x07,0x06,0x06,0x06,0x06,0x06, + 0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05, + 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03, + 0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}; + + +void InitSpeaker(void) +{ + asm CLI; + outportb(0x43,0x90); /* Prepara el Timer 2: Acceso MSB y modo terminal */ + outportb(0x61,inportb(0x61) | 3); /* Hace que el speaker funcione con el timer 2 */ + asm STI; +} + +void CloseSpeaker(void) +{ + asm CLI; + outportb(0x61,inportb(0x61) & 0xFC); /* Para el altavoz */ + outportb(0x43,0xB6); /* Restaura el valor del registro de control del Timer 2 */ + asm STI; +} + +void SpkSendByte(unsigned char b) +{ + outportb(0x42,TablaSpeaker[b]); +} diff --git a/WAVPLAV/SPEAKER.H b/WAVPLAV/SPEAKER.H new file mode 100644 index 0000000..bd9700a --- /dev/null +++ b/WAVPLAV/SPEAKER.H @@ -0,0 +1,3 @@ +void InitSpeaker(void); +void CloseSpeaker(void); +void SpkSendByte(unsigned char b); diff --git a/WAVPLAV/SPEAKER.OBJ b/WAVPLAV/SPEAKER.OBJ new file mode 100644 index 0000000..b3cf948 Binary files /dev/null and b/WAVPLAV/SPEAKER.OBJ differ diff --git a/WAVPLAV/VOCPLAY.CPP b/WAVPLAV/VOCPLAY.CPP new file mode 100644 index 0000000..c0cbee3 --- /dev/null +++ b/WAVPLAV/VOCPLAY.CPP @@ -0,0 +1,406 @@ +#include + +#include +#include +#include + +#include +#include +#include + +#include "sb.h" +#include "dac.h" +#include "speaker.h" +#include "Wavplay.h" + +#define FALSE 0 +#define TRUE 1 + +#define ERROR_ABRIENDO 2 +#define SIN_MEMORIA 3 +#define FICHERO_ENORME 4 + +char huge *pWav, /* Puntero a la digitalizacin */ + huge *pMuestra; /* Puntero a la muestra que suena */ + long Tamanyo, /* Tamao de los datos */ + T_Real; + +unsigned + Divisor, /* Valor del divisor del Timer 0 */ + Frec=11000; /* Frecuencia de muestreo */ +char FinVoz; /* Indica si la digitalizacin ha terminado de sonar */ +void interrupt (*Antigua8)(...); /* Antigua INT 8 */ + +void (*ByteAlDAC)(unsigned char); /* Puntero a la funcin que enva el byte al DAC */ + +char Wav_Mem = 0, Init = 0, SB_SPK = 0, Old_File[80]; + +int CargaWav(char *Nombre, long Pos, long Len); +void DeInitSB(void); +int InitSB(void); + +int Condicion_S00(void); + +int PlayWav(char far *File, long Pos, long Len ); + +int PlayLongWav(char far *File, long Pos, long Len); + +void ProgFrec(unsigned *Frecuencia); +void interrupt Nuestra8(...); +void ProgTimer0(unsigned Divisor); + +//int far TeclaPulsada(void); + +/* +int main(int argc, char *argv[]) +{ + if (argc<2) + { + printf("Error: falta parmetro necesario.\n"); + printf(" Fichero Salida\n"); + printf(" Salida --> 0 Speaker\n"); + printf(" --> 1 SB\n"); + printf(" --> 2 Dac\n"); + return(1); + } + + InitSB(); + + if ( argc == 3 ) SB_SPK = atoi(argv[2]); + + + if ( PlayWav(argv[1],TeclaPulsada) != 0 ) + PlayLongWav(argv[1],TeclaPulsada); + + + return 0; +} +*/ + +/* *//* *//**/ +/* *//* *//**/ +/* *//* *//**/ +/* *//* *//**/ +/* *//* JD*//**/ + +int CargaWav(char *Nombre, long Pos, long Len) +{ + FILE *handle_sonido; + long tam = 0; + + + if( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } + + if((handle_sonido = fopen(Nombre, "rb"))==NULL) { + return ERROR_ABRIENDO; + } + + if( (Tamanyo = + ( (Len==-1) ? + filelength(fileno(handle_sonido))-32 + : + Len - 32 + ) + ) < 1 ) { T_Real = 0; return ERROR_ABRIENDO; } + + fseek( handle_sonido, Pos, SEEK_SET ); + + T_Real = Tamanyo; + + if ( (pWav = (char huge *)farmalloc(Tamanyo+32) ) == NULL ) { + fclose(handle_sonido); + return SIN_MEMORIA; + } + Wav_Mem = 1; + pMuestra = pWav; + + fread(pMuestra, sizeof(char), 24, handle_sonido); // C A B E C E R A . . . + + fread(&Frec, sizeof(unsigned int), 1, handle_sonido); // C A B E C E R A . . . + + if ( Frec <2000 ) Frec = 11025; + + fread(pMuestra, sizeof(char), 6, handle_sonido); // C A B E C E R A . . . + + pMuestra = pWav; + + while( tam < (Tamanyo + 1)) { + tam++; *pMuestra++ = getc(handle_sonido); +//if(pWav == pMuestra) printf("\nEl puntero esta en el origen o dio la vuelta durante la carga... %ld\n", tam); + } + + pMuestra = pWav; + + fclose(handle_sonido); + return 1; + +} + + +void ProgTimer0(unsigned Divisor) +/* Programa el Timer 0 para que cuente desde Divisor hasta 0 */ +{ + asm CLI; /* Inhabilitamos interrupciones: seccin crtica */ + outportb(0x43,0x36); /* 00111010: Timer 0, acceso secuencial y modo contnuo */ + outportb(0x40,Divisor & 0xFF); /* Byte bajo del contador */ + outportb(0x40,Divisor >> 8); /* Byte alto del contador */ + asm STI; /* Fin de seccin crtica */ +} + +void ProgFrec(unsigned *Frecuencia) +/* Programa el Timer 0 para que genere "Frecuencia" interrupciones por segundo */ +{ + Divisor = 1193180 / *Frecuencia; + *Frecuencia = 1193180 / Divisor; + ProgTimer0(Divisor); +} + +void interrupt Nuestra8(...) +{ + if (!FinVoz) + { + (*ByteAlDAC)(*pMuestra); + pMuestra++; + Tamanyo--; + if (Tamanyo<=1) FinVoz = TRUE; + } + outportb(0x20,0x20); /* Indicamos al controlador de interrupciones */ +} /* que la interrupcin ha sido atendida */ + +void DeInitSB(void){ + + if ( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } + +} + +int InitSB(void){ + + if ( Init == 0 ) + atexit( DeInitSB ); + + Init = 1; + return ( ( SBDetect() != -1 ) ? ( SB_SPK = 1 ) : ( SB_SPK = 0 ) ); + +} + +/**//* *//**/ +/**//* *//**/ +/**//* *//**/ +/**//* *//**/ +/**//* JD*//**/ +int PlayWav(char far *File, long Pos, long Len) +{ +static long Old_Pos = -1; + +if( Len == -1 ) { + if ( strcmpi( File, Old_File ) != 0 || !Wav_Mem ) { + if ( CargaWav(File, Pos, Len) != 1 ) { strcpy( Old_File, "\0" ); return (-1); } + strcpy( Old_File, File ); + } else { + + pMuestra = pWav; + Tamanyo = T_Real; + + } +} else { + if ( Old_Pos != Pos || !Wav_Mem ) { + if ( CargaWav(File, Pos, Len) != 1 ) { strcpy( Old_File, "\0" ); return (-1); } + Old_Pos = Pos; + } else { + pMuestra = pWav; + Tamanyo = T_Real; + + } +} + + switch ( SB_SPK ) { + case 0: + InitSpeaker(); + FinVoz = TRUE; + ByteAlDAC = SpkSendByte; + break; + case 1: + FinVoz = TRUE; + ByteAlDAC = SBSendByte; + break; + case 2: + InitDAC(); + FinVoz = TRUE; + ByteAlDAC = LPT1DAC; + break; + default: + return -1; + } + + Antigua8 = getvect(8); /* Guardamos el puntero a la antigua INT 8 */ + setvect(8,Nuestra8); /* Colocamos el puntero a nuestra rutina */ + ProgFrec(&Frec); + FinVoz = FALSE; + + while (!FinVoz && !Condicion_S00() ); + +// /* if ( !*/Condicion_S00() /*) while (!FinVoz)*/; + ProgTimer0(0); + CloseSpeaker(); + setvect(8,Antigua8); + + return(0); + +} + + + + + +int PlayLongWav(char far *File, long Pos, long Len) +{ + const int Buff = 4096; + + FILE *handle_sonido; + long n_lecturas, pico_lectr; + char parte=0, key; + + if( Wav_Mem == 1 ) { farfree( pWav ); Wav_Mem = 0; } + + if((handle_sonido = fopen(File, "rb"))==NULL) { + return ERROR_ABRIENDO; + } + + if( (Tamanyo = + ( (Len==-1) ? + filelength(fileno(handle_sonido))-32 + : + Len - 32 + ) + ) < 1 ) { T_Real = 0; return ERROR_ABRIENDO; } + + fseek( handle_sonido, Pos, SEEK_SET ); + + T_Real = Tamanyo; + + n_lecturas = Tamanyo / Buff; + pico_lectr = Tamanyo - ( n_lecturas * Buff ); + + if ( (pWav = (char huge *)farmalloc(Buff*2) ) == NULL ) { + fclose(handle_sonido); + return SIN_MEMORIA; + } + Wav_Mem = 1; + pMuestra = pWav; + +// fread(pMuestra, sizeof(char), 32, handle_sonido); // C A B E C E R A . . . + fread(pMuestra, sizeof(char), 24, handle_sonido); // C A B E C E R A . . . + + fread(&Frec, sizeof(unsigned int), 1, handle_sonido); // C A B E C E R A . . . + + if ( Frec <2000 ) Frec = 8050; + + fread(pMuestra, sizeof(char), 6, handle_sonido); // C A B E C E R A . . . + + if(n_lecturas) { + fread(pWav, sizeof(char), Buff, handle_sonido); + Tamanyo = Buff; + } else { + fread(pWav, sizeof(char), pico_lectr, handle_sonido); + Tamanyo = pico_lectr; + } + + + switch ( SB_SPK ) { + case 0: + InitSpeaker(); + FinVoz = TRUE; + ByteAlDAC = SpkSendByte; + break; + case 1: + FinVoz = TRUE; + ByteAlDAC = SBSendByte; + break; + case 2: + InitDAC(); + FinVoz = TRUE; + ByteAlDAC = LPT1DAC; + break; + default: + return -1; + } + + Antigua8 = getvect(8); /* Guardamos el puntero a la antigua INT 8 */ + setvect(8,Nuestra8); /* Colocamos el puntero a nuestra rutina */ + ProgFrec(&Frec); + FinVoz = FALSE; + + parte = 1; + + + + if ( n_lecturas > 0 ) { + + while( n_lecturas > 0 ){ // Ejecutamos tantas veces con Lecturas Buff se + // puedan hacer... + + n_lecturas--; // Vaya se nos fue una lectura... + + if ( n_lecturas > 0 ) { // Si quedan lecturas... llenamos el Doble Buffer + + if( parte ) fread( (pWav+4096), sizeof(char), Buff, handle_sonido ); + else fread( (pWav ), sizeof(char), Buff, handle_sonido ); + + } else + if ( pico_lectr > 0) { + if( parte ) fread( (pWav+4096), sizeof(char), pico_lectr, handle_sonido ); + else fread( (pWav ), sizeof(char), pico_lectr, handle_sonido ); + } + + + while (!FinVoz && !(key = Condicion_S00() ) ); +// if ( !(key = Condicion()) ) while (!FinVoz); + if ( key ) { FinVoz = TRUE; break; } + + + if ( (n_lecturas > 0 || pico_lectr !=0) && !key ) { + if( parte ){ parte = 0; /* Ya colocado */} + else { parte = 1; pMuestra = pWav; } + + if (n_lecturas > 0) Tamanyo = Buff; else Tamanyo = pico_lectr; + FinVoz = FALSE; + + } + + } + + while (!FinVoz && !Condicion_S00()); +// if ( !(Condicion()) ) while (!FinVoz); +} else + while (!FinVoz && !Condicion_S00()); +// if ( !(Condicion()) ) while (!FinVoz); + + ProgTimer0(0); + CloseSpeaker(); + setvect(8,Antigua8); + + fclose(handle_sonido); + DeInitSB(); + return(0); + +} + + +// int far TeclaPulsada(void) +/* Esta funcin mira si se ha pulsado una tecla pero SIN llamadas a la BIOS, + de forma que no se inhabilitan las interrupciones en cada llamada, cosa + que bajara mucho la calidad de reproduccin con el altavoz interno. */ +// { +// return ( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ); +// } + +int Condicion_S00(void) +{ + + union REGS RaT; + RaT.x.ax = 3; + int86(0x33, &RaT, &RaT); + + return (( *(unsigned *) MK_FP(0x40,0x1A) != *(unsigned *) MK_FP(0x40,0x1C) ) || (RaT.x.bx & 1)); + +} \ No newline at end of file diff --git a/WAVPLAV/VOCPLAY.OBJ b/WAVPLAV/VOCPLAY.OBJ new file mode 100644 index 0000000..f52e12c Binary files /dev/null and b/WAVPLAV/VOCPLAY.OBJ differ diff --git a/WAVPLAV/WAVPLAY.H b/WAVPLAV/WAVPLAY.H new file mode 100644 index 0000000..2a3e000 --- /dev/null +++ b/WAVPLAV/WAVPLAY.H @@ -0,0 +1,75 @@ + + + +//******************************************/ +//**/ /**/ +//**/ Funcion encargada de inicializar /**/ +//**/ la Sb, Speaker, o DAC... /**/ +//******************************************/ +extern int InitSB(void); + +//******************************************/ +//**/ /**/ +//**/ Funcion encargada de desconectar /**/ +//**/ la Sb, Speaker, o DAC... /**/ +//******************************************/ +extern void DeInitSB(void); + + + //****************************************** ;El fichero Wav debe estar grabado +///**/ Carga y Toca un fichero WAV o Wav' /** ;a 8050 Hz. +///**/ Se le pasan el Nombre del Fichero /** +///**/ y un puntero a la funcion que /** ;Devuelve un 0 si todo ha ido +///**/ determinara cuando se interrumpira /** ;bien... +///**/ el sonido antes del final del mismo/** +///****************************************** +/////////////////////////////////////////// +extern int PlayWav(char *File, long Pos, long Len); + + /******************************************/ + //**/ Igual que PlayWav... /**/ +///**/ /**/ +///**/ Solo que sirve para reproducir /**/ +///**/ ficheros WAV de 300.000 Mb de /**/ +///**/ Tamanyo utilizando solo un doble /**/ +///**/ buffer de 8K /**/ +///**/ /**/ +///******************************************/ +/////////////////////////////////////////// +extern int PlayLongWav(char *File, long Pos, long Len); + + /******************************************/ + //**/ Mira si se ha pulsado una tecla /**/ +///**/ pero sin utilizar la BIOS ni /**/ +///**/ interruppir las interrupciones /**/ +///******************************************/ +/////////////////////////////////////////// +extern int far TeclaPulsada(void); + +/// SB_SPK :: Aunque esta variable se carga sola cuando se inicializa +/// la SB, se puede forzar a cargarla manualmente... +/// +/// V A L O R Salida del sonido digitalizado +/// +/// 0 Speaker +/// 1 Sound Blaster +/// 2 Dac Casero... +extern char SB_SPK; + +/// WARNING !!!!! +/// +/// Las variables a continuacin enseladas no deben se modificadas y si +/// estan hay es solo para que puedas, si lo deseas, realizar un seguimiento +/// de los datos que estan sonando... + +extern char huge *pMuestra; /* Puntero a la muestra que suena */ +extern long Tamanyo, /* Tamao de los datos que estan sonando */ + T_Real; /* Tamao real de los datos */ + +// Nota: + +// Con PlayLongWav como es natural no se puede cargar un WAV de 300.000 Mb +// en memoria por lo que Tamanyo != T_Real e indica el tamao de la muestra +// que queda por reproducir, en bytes. +// + diff --git a/WAVPLAV/WAVPLAYC.LIB b/WAVPLAV/WAVPLAYC.LIB new file mode 100644 index 0000000..0b9ee38 Binary files /dev/null and b/WAVPLAV/WAVPLAYC.LIB differ