Advertisement
Guest User

Untitled

a guest
Dec 12th, 2013
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.32 KB | None | 0 0
  1. /*  FastAri 0.3 - A Fast Block-Based Bitwise Arithmetic Compressor
  2. Copyright (C) 2013  David Catt
  3.  
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program.  If not, see <http://www.gnu.org/licenses/>. */
  16.  
  17. #include <stdlib.h>
  18. #define ORDER 17
  19. #define ADAPT 4
  20. const int mask = (1 << ORDER) - 1;
  21. int fa_compress(const unsigned char* ibuf, unsigned char* obuf, size_t ilen, size_t* olen) {
  22.     unsigned int low=0, mid, high=0xFFFFFFFF;
  23.     size_t ipos, opos=0;
  24.     int bp, bv;
  25.     int ctx;
  26.     /* Initialize model */
  27.     unsigned short* mdl = malloc((mask + 1) * sizeof(unsigned short));
  28.     if(!mdl) return 1;
  29.     for(ctx = 0; ctx <= mask; ++ctx) mdl[ctx] = 0x8000;
  30.     ctx = 0;
  31.     /* Walk through input */
  32.     for(ipos = 0; ipos < ilen; ++ipos) {
  33.         bv = ibuf[ipos];
  34.         for(bp = 7; bp >= 0; --bp) {
  35.             mid = low + (((high - low) >> 16) * mdl[ctx]);
  36.             if(bv&1) {
  37.                 high = mid;
  38.                 mdl[ctx] += (0xFFFF - mdl[ctx]) >> ADAPT;
  39.                 ctx = ((ctx << 1) | 1) & mask;
  40.             } else {
  41.                 low = mid + 1;
  42.                 mdl[ctx] -= mdl[ctx] >> ADAPT;
  43.                 ctx = (ctx << 1) & mask;
  44.             }
  45.             bv >>= 1;
  46.             while((high ^ low) < 0x1000000) {
  47.                 obuf[opos] = high >> 24;
  48.                 ++opos;
  49.                 high = (high << 8) | 0xFF;
  50.                 low <<= 8;
  51.             }
  52.         }
  53.     }
  54.     /* Flush coder */
  55.     obuf[opos] = (high >> 24); ++opos;
  56.     obuf[opos] = (high >> 16) & 0xFF; ++opos;
  57.     obuf[opos] = (high >> 8) & 0xFF; ++opos;
  58.     obuf[opos] = high & 0xFF; ++opos;
  59.     /* Cleanup */
  60.     free(mdl);
  61.     *olen = opos;
  62.     return 0;
  63. }
  64. #include <stdio.h>
  65. int fa_decompress(const unsigned char* ibuf, unsigned char* obuf, size_t ilen, size_t* olen) {
  66.     unsigned int low = 0, mid, high = 0xFFFFFFFF, cur = 0, c;
  67.     size_t opos = 0;
  68.     int bp, bv;
  69.     int ctx;
  70.     const unsigned char* ibuf_end = ibuf + ilen;
  71.     /* Initialize model */
  72.     unsigned short* mdl = malloc((mask + 1) * sizeof(unsigned short));
  73.     if(!mdl) return 1;
  74.     for(ctx = 0; ctx <= mask; ++ctx) mdl[ctx] = 0x8000;
  75.     ctx = 0;
  76.     /* Initialize coder */
  77.     cur = (cur << 8) | *ibuf; ++ibuf;
  78.     cur = (cur << 8) | *ibuf; ++ibuf;
  79.     cur = (cur << 8) | *ibuf; ++ibuf;
  80.     cur = (cur << 8) | *ibuf; ++ibuf;
  81.     /* Walk through input */
  82.     while(opos < *olen) {
  83.         bv = 0;
  84.         for(bp = 0; bp < 8; ++bp) {
  85.             /* Decode bit */
  86.             mid = low + (((high - low) >> 16) * mdl[ctx]);
  87.             if(cur <= mid) {
  88.                 high = mid;
  89.                 mdl[ctx] += (0xFFFF - mdl[ctx]) >> ADAPT;
  90.                 bv |= (1 << bp);
  91.                 ctx = ((ctx << 1) | 1) & mask;
  92.             } else {
  93.                 low = mid + 1;
  94.                 mdl[ctx] -= mdl[ctx] >> ADAPT;
  95.                 ctx = (ctx << 1) & mask;
  96.             }
  97.             while((high ^ low) < 0x1000000) {
  98.                 if (ibuf > ibuf_end) {
  99.                     free(mdl);
  100.                     *olen = opos;
  101.                     return 0;
  102.                 }
  103.                 high = (high << 8) | 0xFF;
  104.                 low <<= 8;
  105.                 c = *ibuf; ++ibuf;
  106.                 cur = (cur << 8) | c;
  107.             }
  108.         }
  109.         *obuf = bv;
  110.         ++obuf;
  111.         ++opos;
  112.     }
  113.     /* Cleanup */
  114.     free(mdl);
  115.     if (ibuf_end == ibuf) {
  116.         *olen = opos;
  117.         return 0;
  118.     } else {
  119.         return 2;
  120.     }
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement