home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / packery / xpk_source / libraries / rlen / xpkrlen.c < prev   
C/C++ Source or Header  |  1996-10-19  |  3KB  |  137 lines

  1. /*
  2.  * This library is mainly intended to demonstrate how to program a sub
  3.  * library.
  4.  */
  5.  
  6. #include <xpk/xpksub.h>
  7.  
  8. #ifdef __MAXON__
  9.   #define __asm
  10. #endif
  11.  
  12. struct XpkMode RlenMode =
  13. {
  14.   NULL,                /* next            */
  15.   100,                /* upto            */
  16.   XPKMF_A3000SPEED,        /* flags        */
  17.   0,                /* packmem        */
  18.   0,                /* unpackmem        */
  19.   140,                /* packspeed, K / sec    */
  20.   1043,                /* unpackspeed, K / sec    */
  21.   45,                /* ratio, *0.1 %    */
  22.   0,                /* reserved        */
  23.   "normal"            /* description        */
  24. };
  25.  
  26. static struct XpkInfo RlenInfo =
  27. {
  28.   1,                /* info version */
  29.   1,                /* lib  version */
  30.   0,                /* master vers  */
  31.   0,                /* pad          */
  32.   "RLEN",            /* short name   */
  33.   "Run Length",            /* long name    */
  34.   "Fast and simple compression usable for simple data",    /* description*/
  35.   0x524C454E,            /* 'RLEN', 4 letter ID  */
  36.   XPKIF_PK_CHUNK |        /* flags        */
  37.   XPKIF_UP_CHUNK,
  38.   0x7fffffff,            /* max in chunk */
  39.   0,                /* min in chunk */
  40.   0x4004,            /* def in chunk */
  41.   NULL,                /* pk message   */
  42.   NULL,                /* up message   */
  43.   NULL,                /* pk past msg  */
  44.   NULL,                /* up past msg  */
  45.   50,                /* def mode     */
  46.   0,                /* pad          */
  47.   &RlenMode            /* modes        */
  48. };
  49.  
  50. /*
  51.  * Returns an info structure about our packer
  52.  */
  53.  
  54. #ifdef __cplusplus
  55.   extern "C"
  56. #endif
  57.  
  58. struct XpkInfo * __asm XpksPackerInfo (void)
  59. {
  60.   return &RlenInfo;
  61. }
  62.  
  63. /*
  64.  * Pack a chunk
  65.  */
  66.  
  67. #ifdef __cplusplus
  68.   extern "C"
  69. #endif
  70.  
  71. LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar)
  72. {
  73.   UBYTE *get = xpar->InBuf, *start = xpar->InBuf;
  74.   UBYTE *end = get + xpar->InLen, *put = xpar->OutBuf;
  75.   UBYTE *wend = put + xpar->OutBufLen;
  76.   LONG run, i;
  77.  
  78.   for (;;)
  79.   {
  80.     run = get[0] == get[1] && get[1] == get[2];
  81.  
  82.     if (put + (get - start) + 4 > wend)
  83.       return XPKERR_EXPANSION;
  84.  
  85.     if (run || get - start == 127 || get == end)
  86.     {    /* write uncompressed */
  87.       if (get - start)
  88.       {
  89.     *put++ = get - start;
  90.     for (i = get - start; i > 0; i--)
  91.       *put++ = *start++;
  92.       }
  93.       if (get == end)
  94.       {
  95.     *put++ = 0;
  96.     break;
  97.       }
  98.       start = get;
  99.     }
  100.  
  101.     if(run)
  102.     {            /* write compressed   */
  103.       for (i = 3; get + i < end && get[i - 1] == get[i] && i < 127; i++);
  104.       *put++ = -i;
  105.       *put++ = get[0];
  106.       get += i;
  107.       start = get;
  108.     }
  109.     else
  110.       get++;
  111.   }
  112.   xpar->OutLen = put - (UBYTE *) xpar->OutBuf;
  113.  
  114.   return 0;
  115. }
  116.  
  117. #ifdef __cplusplus
  118.   extern "C"
  119. #endif
  120.  
  121. LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
  122. {
  123.   STRPTR get = xpar->InBuf, put = xpar->OutBuf;
  124.   UBYTE v;
  125.   LONG i;
  126.  
  127.   while (i = *get++)
  128.     if (i > 0)
  129.       for (; i > 0; i--)
  130.     *put++ = *get++;
  131.     else
  132.       for (i = -i, v = *get++; i > 0; i--)
  133.     *put++ = v;
  134.  
  135.   return 0;
  136. }
  137.