home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
packery
/
xpk_source
/
libraries
/
rlen
/
xpkrlen.c
< prev
Wrap
C/C++ Source or Header
|
1996-10-19
|
3KB
|
137 lines
/*
* This library is mainly intended to demonstrate how to program a sub
* library.
*/
#include <xpk/xpksub.h>
#ifdef __MAXON__
#define __asm
#endif
struct XpkMode RlenMode =
{
NULL, /* next */
100, /* upto */
XPKMF_A3000SPEED, /* flags */
0, /* packmem */
0, /* unpackmem */
140, /* packspeed, K / sec */
1043, /* unpackspeed, K / sec */
45, /* ratio, *0.1 % */
0, /* reserved */
"normal" /* description */
};
static struct XpkInfo RlenInfo =
{
1, /* info version */
1, /* lib version */
0, /* master vers */
0, /* pad */
"RLEN", /* short name */
"Run Length", /* long name */
"Fast and simple compression usable for simple data", /* description*/
0x524C454E, /* 'RLEN', 4 letter ID */
XPKIF_PK_CHUNK | /* flags */
XPKIF_UP_CHUNK,
0x7fffffff, /* max in chunk */
0, /* min in chunk */
0x4004, /* def in chunk */
NULL, /* pk message */
NULL, /* up message */
NULL, /* pk past msg */
NULL, /* up past msg */
50, /* def mode */
0, /* pad */
&RlenMode /* modes */
};
/*
* Returns an info structure about our packer
*/
#ifdef __cplusplus
extern "C"
#endif
struct XpkInfo * __asm XpksPackerInfo (void)
{
return &RlenInfo;
}
/*
* Pack a chunk
*/
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar)
{
UBYTE *get = xpar->InBuf, *start = xpar->InBuf;
UBYTE *end = get + xpar->InLen, *put = xpar->OutBuf;
UBYTE *wend = put + xpar->OutBufLen;
LONG run, i;
for (;;)
{
run = get[0] == get[1] && get[1] == get[2];
if (put + (get - start) + 4 > wend)
return XPKERR_EXPANSION;
if (run || get - start == 127 || get == end)
{ /* write uncompressed */
if (get - start)
{
*put++ = get - start;
for (i = get - start; i > 0; i--)
*put++ = *start++;
}
if (get == end)
{
*put++ = 0;
break;
}
start = get;
}
if(run)
{ /* write compressed */
for (i = 3; get + i < end && get[i - 1] == get[i] && i < 127; i++);
*put++ = -i;
*put++ = get[0];
get += i;
start = get;
}
else
get++;
}
xpar->OutLen = put - (UBYTE *) xpar->OutBuf;
return 0;
}
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
{
STRPTR get = xpar->InBuf, put = xpar->OutBuf;
UBYTE v;
LONG i;
while (i = *get++)
if (i > 0)
for (; i > 0; i--)
*put++ = *get++;
else
for (i = -i, v = *get++; i > 0; i--)
*put++ = v;
return 0;
}