⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmc.cpp

📁 zlib-1.2.3.tar是新的zlib库藏 用于压缩 等等
💻 CPP
字号:
/*   Dynamic Markov Compression (DMC)    Version 0.0.0
 
 
     Copyright 1993, 1987
 
     Gordon V. Cormack
     University of Waterloo
     cormack@uwaterloo.ca
 
 
     All rights reserved.
 
     This code and the algorithms herein are the property of Gordon V. Cormack.
 
     Neither the code nor any algorithm herein may be included in any software,
     device, or process which is sold, exchanged for profit, or for which a
     licence or royalty fee is charged.
 
     Permission is granted to use this code for educational, research, or
     commercial purposes, provided this notice is included, and provided this
     code is not used as described in the above paragraph.
 
*/

/*    This program implements DMC as described in

      "Data Compression using Dynamic Markov Modelling",
      by Gordon Cormack and Nigel Horspool
      in Computer Journal 30:6 (December 1987)

      It uses floating point so it isn't fast.  Converting to fixed point
      isn't too difficult.

      comp() and exp() implement Guazzo's version of arithmetic coding.

      pinit(), predict(), and pupdate() are the DMC predictor.

      pflush() reinitializes the DMC table and reclaims space

      preset() starts the DMC predictor at its start state, but doesn't
               reinitialize the tables.  This is used for packetized
               communications, but not here.

*/

/* JC [06/01/2000] Converted to ANSI C++, fixed up for ComprLib */

#include <stdio.h>

#include "codec.h"

static float predict();
static int pinit(int);
static int pupdate(int);
static int pflush();
static int preset();

int memsize = 0x1000000;

int encode_dmc(){ /* compression -- was comp() */
   int max = 0x1000000,
       min = 0,
       mid,
       c,i,
       inbytes = 0, 
       outbytes =3,
       pout = 3,
       bit;
   
   pinit(memsize);
   
   for(;;){
      c = read_byte();
      /* if (c == EOF) { */
      if (end_of_data()) {
         min = max-1;
         break;
      }
      for (i=0;i<8;i++){
         bit = (c << i) & 0x80;
         mid = (int)(min + (max-min-1) * predict());
         pupdate(bit != 0);
         if (mid == min) mid++;
         if (mid == (max-1)) mid--;
   
         if (bit) { 
            min = mid;
         } else {
            max = mid;
         }
         while ((max-min) < 256) {
            if(bit)max--;
            write_byte(min >> 16);
            outbytes++;
            min = (min << 8) & 0xffff00;
            max = ((max << 8) & 0xffff00 ) ;
            if (min >= max) max = 0x1000000;
         }
      }
      if(!(++inbytes & 0xff)){
         if(!(inbytes & 0xffff)){
         }
         if (outbytes - pout > 256) { /* compression failing */
            pflush();
         }
         pout = outbytes;
      }
   }
   write_byte(min>>16);
   write_byte((min>>8) & 0xff);
   write_byte(min & 0x00ff);
   return 0;
}


int decode_dmc(){ /* expand -- was exp() */
   int max = 0x1000000,
       min = 0,
       mid,
       val,
       i,
       inbytes=3,
       pin=3,
       outbytes=0,
       bit,
       c;
   
   pinit(memsize);
   
   val = read_byte()<<16;
   val += read_byte()<<8;
   val += read_byte();
   while(1) {
      c = 0;
      if (val == (max-1)) {
         break;
      }
      for (i=0;i<8;i++){
         mid = (int)(min + (max-min-1)*predict());
         if (mid == min) mid++;
         if (mid == (max-1)) mid--;
         if (val >= mid) {
            bit = 1;
            min = mid;
         } else {
            bit = 0;
            max = mid;
         }
         pupdate(bit != 0);
         c = c + c + bit;
         while ((max-min) < 256) {
            if(bit)max--;
            inbytes++;
            val = (val << 8) & 0xffff00 | (read_byte()& 0xff);
            min = (min << 8) & 0xffff00;
            max = ((max << 8) & 0xffff00 ) ;
            if (min >= max) max = 0x1000000;
         }
      }
      write_byte(c);
      if(!(++outbytes & 0xff)){
         if (inbytes - pin > 256) { /* compression was failing */
            pflush();
         }
         pin = inbytes;
      }
   }
   return 0;
}

typedef struct nnn {
           float count[2];
           struct nnn    *next[2];
} node;

static int threshold = 2, bigthresh = 2; 

static node *p, *newn, nodes[256][256];

static node *nodebuf;
static node *nodemaxp;
static node *nodesptr;

#include <malloc.h>

int pinit(int memsize)
{
   nodebuf = (node *) malloc (memsize);
   if (nodebuf == (node *) NULL) {
      exit(1);
   }
   nodemaxp = nodebuf + (memsize/sizeof(node)) - 20;
   pflush();
   return 0;
}

int pflush(){
   int i,j;
   for (j=0;j<256;j++){
      for (i=0;i<127;i++) {
         nodes[j][i].count[0] = 0.2;
         nodes[j][i].count[1] = 0.2;
         nodes[j][i].next[0] = &nodes[j][2*i + 1];
         nodes[j][i].next[1] = &nodes[j][2*i + 2];
      }
      for (i=127;i<255;i++) {
         nodes[j][i].count[0] = 0.2;
         nodes[j][i].count[1] = 0.2;
         nodes[j][i].next[0] = &nodes[i+1][0];
         nodes[j][i].next[1] = &nodes[i-127][0];
      }
   }
   nodesptr = nodebuf;
   preset();
   return 0;
}

int preset(){
   p = &nodes[0][0];
   return 0;
}

float predict(){
   return   p->count[0] / (p->count[0] + p->count[1]);
}

int pupdate(int b)
{
   float r;
   if (p->count[b] >= threshold &&
      p->next[b]->count[0]+p->next[b]->count[1]
       >= bigthresh + p->count[b]){
      newn = nodesptr++;
      p->next[b]->count[0] -= newn->count[0] =
         p->next[b]->count[0] * 
         (r = p->count[b]/(p->next[b]->count[1]+p->next[b]->count[0]));
      p->next[b]->count[1] -= newn->count[1] =
         p->next[b]->count[1] * r;
      newn->next[0] = p->next[b]->next[0];
      newn->next[1] = p->next[b]->next[1];
      p->next[b] = newn;
   }
   p->count[b]++;
   p = p->next[b];
   if (nodesptr > nodemaxp){
      pflush();
   }
   return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -