home *** CD-ROM | disk | FTP | other *** search
-
-
- /**-----------------------------------------------------------------------
- * Bloque de includes, por fin me ocupan menos de una pagina de
- * impresisn, lo que hay que hacer para tener todos los prototipos..
- *
- **/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <fcntl.h>
-
- #define NO_SUB_PRAGMAS
- #include <libraries/xpksub.h>
-
- #include "cbitio.h" /* custom includes */
- #include "ilzr.h"
-
- /**-----------------------------------------------------------------------
- * Prototipos para todas estas paridas necesarias para compilar.
- *
- **/
-
-
- /**-----------------------------------------------------------------------
- * En un principio utilizaba la funcisn de HASH del COMRESS de GNU en
- * UNIX, pero por motivos de eficiencia he tenido que cambiarla. La forma
- * actual se inspira en el algoritmo de Rabin & Karp ( En el libro :
- * "Algorithms" de Sedgewick de Addison-Wesley p.252 )
- *
- **/
-
- #define BestMatch( scan , matchpos , bestlen ) \
- { \
- if( (xparinbuf + matchpos) <= scan ) \
- { \
- ioaux = 0; \
- bestlen = MIN_MATCH - 1; \
- scanend = scan[ bestlen ]; \
- strend = scan + MAX_MATCH; \
- current = matchpos; \
- lastmatch= matchpos; \
- while( current != NIL && lastmatch >= current ) \
- { \
- match = xparinbuf + current; \
- if( match[ bestlen ] != scanend || \
- *match != *scan || \
- *++match != scan[1] ) \
- { \
- lastmatch = current; \
- current = prev[ current ]; \
- ioaux++; \
- if( ioaux > MAX_HASH_COL ) \
- break; \
- continue; \
- } \
- scan+=2; /* do not try to put in the if condition */ \
- match++; \
- do \
- { \
- }while( *++scan == *++match && *++scan == *++match && \
- *++scan == *++match && *++scan == *++match && \
- *++scan == *++match && *++scan == *++match && \
- *++scan == *++match && *++scan == *++match && \
- scan < strend ); /* Estraqo pero mejor codigo */ \
- conta = MAX_MATCH - (UBYTE)(strend - scan); /* len para ahorrar */\
- scan = strend - MAX_MATCH; \
- if( conta > bestlen ) \
- { \
- bestlen = conta; \
- matchpos = current; \
- if( conta >= MAX_MATCH ) \
- break; \
- scanend = scan[ bestlen ]; \
- } \
- lastmatch = current; \
- current = prev[ current ]; \
- } \
- } \
- }
-
-
- /**-----------------------------------------------------------------------
- * En pocas lineas se adentrara al nucleo de todo el sistema de
- * compresisn de datos, aunque parezca mentira intentare que el
- * sistema mantenga el coste ideal mmnimo, coste LINEAL??.
- * Esto son las mejores intenciones, ya veremos en que se nos queda.
- *
- **/
-
- long __saveds __asm XpksPackChunk( REG __a0 XPARAMS *xpar )
- {
- /* variables para input - output */
- register UBYTE outmask;
- register CHARS *inpb;
- CHARS *endinp;
- register CHARS *outb;
- CHARS *endout;
- ULONG ioaux; /* tambien se usa en BestMach */
- UBYTE endoffile;
-
- /* varialbles utilizadas en BestMach */
- CHARS scanend;
- CHARS *strend;
- register CHARS *match;
- UWORD current;
- UWORD lastmatch;
-
- /* bloque general de compres */
- UBYTE lookahead; /* siempre RAW_LOOKAHEAD < 255 */
- UBYTE matchlen; /* siempre RAW_LOOKAHEAD < 255 */
- UBYTE replace; /* cuanto se ha de ampliar "lookahead" */
- UBYTE conta; /* tambien se usa en BestMach */
-
- long bitcount; /* es un LONG para compatibilidad */
- CHARS *bumpcode;
-
- long temp;
-
- CHARS *xparinbuf; /* todo el mundo la utiliza */
- UWORD hash_key; /* actual hash value */
- UWORD matchpos; /* position of matchlen */
- register CHARS *actp; /* posicion en wwindow fich */
- register UWORD *head; /* dictionary */
- register UWORD *prev; /* previous in the hash line */
-
- /**
- * Bloque de inicializacsn + reserva de memoria para las tablas
- *
- **/
-
- if( !xpar->Sub[0] )
- {
- if( !(head = malloc( sizeof( UWORD ) * HASH_SIZE )) )
- return( XPKERR_NOMEM );
-
- if( !(prev = malloc( sizeof( UWORD ) * (WIND_SIZE+MAX_MATCH) ) ) )
- {
- free( head );
- return( XPKERR_NOMEM );
- }
- xpar->Sub[0]=(long)prev;
- xpar->Sub[1]=(long)head;
- }
- else
- {
- prev= (UWORD *)xpar->Sub[0];
- head= (UWORD *)xpar->Sub[1];
- }
-
- /* previous y wwindow se autoinilizalizan */
-
- memset( head , NIL , HASH_SIZE*sizeof( UWORD ) ); /* head */
-
- InitOutput();
- InitInput();
- endoffile = 0;
-
- temp = xpar->InLen;
- OutputBits( temp , 16 ); /* NEED store the long of this block */
-
- xparinbuf = xpar->InBuf;
- bitcount = INIT_BIT_BUMP;
- bumpcode = xparinbuf+(1<<INIT_BIT_BUMP);
-
- matchpos = 0; /* No hace falta pero evita un WARNING */
- matchlen = 0;
- actp = xparinbuf;
- hash_key = 0;
-
- /**
- * Bloque de la precarga necesaria para poder empezar el bucle
- *
- **/
-
- for( conta = 1 ; conta <= MAX_MATCH && !EndOfFile() ; conta++ )
- InputByte( );
-
- lookahead = conta-2;
-
- if( conta > 3 )
- {
- REHASH( hash_key , actp[1] );
- REHASH( hash_key , actp[2] );
- }
-
- /**
- * Comienzo del bucle principal para la compresisn de datos
- *
- **/
-
- while( lookahead > 0 )
- {
- if( matchlen > lookahead )
- matchlen = lookahead;
-
- if( matchlen < MIN_MATCH ) /* Sale a cuenta 2 bloque ? */
- {
- replace=1;
- OutputBit( 1 );
- temp=(long)*actp;
- OutputBits( temp , BITS_CHARS );
- }
- else
- {
- replace=matchlen;
- if( actp > bumpcode )
- {
- bitcount++;
- bumpcode = xparinbuf + (1<<bitcount);
- }
- OutputBit( 0 );
- temp = (long)matchpos;
- OutputBits( temp , bitcount );
- temp= (long)(matchlen - MIN_MATCH );
- OutputBits( temp , BITS_LOOKAHEAD );
- }
-
- for( conta = 0 ; conta < replace ; conta++ )
- {
- if( EndOfFile() )
- lookahead--;
- else
- InputByte( );
-
- actp++;
-
- REHASH( hash_key , actp[ MIN_MATCH -1 ] );
-
- temp = (long)(actp - xparinbuf);
- prev[ temp ] = matchpos = head [ hash_key ];
- head[ hash_key ] = ( UWORD )temp;
- }
-
- BestMatch( actp , matchpos , matchlen ); /* potente macro eh !! */
- }
-
- /**
- * No hace falta indicador de final de fichero pues se siempre
- * la longitud, tampoco libero los recursos, de esto se encarga
- * XpkPackFree
- *
- **/
- xpar->OutLen = (long)outb - (long)xpar->OutBuf + 1; /* CUrIosO */
-
- return( 0 );
- }
-
- /************************** End of ILZR.C *************************/
-