/* * * File: pack.c * Project: libpict 1.1 * Date: Fri, May 19, 1995 * (c) SPDsoft 1992-95 * */ #include #include #include "pict.h" #define MAX_CF 127 #define MIN_CF -127 #define MCFV 128 /*MAX_CF+1*/ #define PSZ BUFSIZ /* Transm. optima a disco */ #if defined(__STDC__) || defined(THINK_C) || !defined(_SUN_) # define _SIGNED signed #else # ifndef _SIGNED # define _SIGNED # endif #endif U_char packed[PSZ], *pEnd, *uEnd; int i; #define GETp { if (p==pEnd) \ { \ incre=MIN2(psz,PSZ); \ fread( (char*)packed,BYTE,(size_t)incre,file); \ psz -= incre; \ p=packed; pEnd = p+incre; \ } \ } #define MIN3(a,b,c) ( i=((a)<(b)?(a):(b)), \ (i<(c)?i:(c) )) #define MIN2(a,b) ((a)<(b)?(a):(b)) #ifdef __STDC__ short int pack_bytes( U_char *unpacked, short int usz, FILE *file ) #else /* __STDC__ */ short int pack_bytes( unpacked, usz, file ) U_char *unpacked; short int usz; FILE *file ; #endif /* __STDC__ */ { U_char *u, *p; /* index unpacked, packed */ _SIGNED char *cf; /* counter flag pointer */ int flgz; /* zero flag */ unsigned short int incre, psz=0; u=unpacked; uEnd=unpacked+usz; pEnd=packed+PSZ-2; while( u=0) /* camb. nuevo rep */ { cf=(_SIGNED char*)p; (*cf)=-1; *(++p)=*u; } } else { if(*cf>=0) /* Mas de bloque no rep */ (*cf)++; else /* Nuevo bloque tipo ? */ { cf=(_SIGNED char *)++p; (*cf)=0; } *(++p)=*u; } } } /* de for */ p++; /* * esta funcion puede ( muy excepcionalmente ) hacer * que los bytes empaquetados ocupen m.s que * los originales, esto puede tener consecuencias * fatales si se usa en ficheros PICT en los que * rowBytes <= 0x00fa ( desborda * la variable corresponiente en el archivo ) */ if ( (int)(u-unpacked)*1.1 < (int)(p-packed )) /* esto se ejecutara rara vez */ for(u=unpacked,p=packed;(u < uEnd)&&(p0;incre--) *p++ = *u++; } fwrite((char *)packed,(size_t)(p-packed),1,file); psz += p-packed ; unpacked = u; }/*while*/ return psz; } #ifdef __STDC__ short int unpack_bytes( U_char *unpacked, short int psz, FILE *file ) #else /* __STDC__ */ short int unpack_bytes( unpacked, psz, file ) U_char *unpacked; short int psz; FILE *file ; #endif /* __STDC__ */ { U_char *u, *p; /* index unpacked, packed */ _SIGNED char cf; /* counter flag */ unsigned short int incre; pEnd=packed+PSZ; u=unpacked; p=pEnd; while((psz>0)||(p!=pEnd)) { GETp; cf = (_SIGNED char) *p++; if(cf >=0) { for(;cf>=0;cf--) { GETp; *u++ = *p++; } } else { GETp; for(;cf<=0;cf++) *u++ = *p; p++; } } return u-unpacked; }