#include <stdio.h>
#include "inttypes.h"
#include "bit_operations.h"
#include "v42bis.h"
/* Fixed parameters from the spec. */
#define V42BIS_N3 8 /* Character size (bits) */
#define V42BIS_N4 256 /* Number of characters in the alphabet */
#define V42BIS_N5 (V42BIS_N4 + V42BIS_N6) /* Index number of first dictionary entry used to store a string */
#define V42BIS_N6 3 /* Number of control codewords */
/* Control code words in compressed mode */
enum
{
V42BIS_ETM = 0, /* Enter transparent mode */
V42BIS_FLUSH = 1, /* Flush data */
V42BIS_STEPUP = 2 /* Step up codeword size */
};
/* Command codes in transparent mode */
enum
{
V42BIS_ECM = 0, /* Enter compression mode */
V42BIS_EID = 1, /* Escape character in data */
V42BIS_RESET = 2 /* Force reinitialisation */
};
static __inline__ void push_compressed_raw_octet(v42bis_compress_state_t *ss, int octet)
{
ss->output_buf[ss->output_octet_count++] = (uint8_t) octet; /*强制转换,舍去高24位?*/
if (ss->output_octet_count >= ss->max_len)
{
ss->handler(ss->user_data, ss->output_buf, ss->output_octet_count);
ss->output_octet_count = 0;
}
}
/*- End of function --------------------------------------------------------*/
static __inline__ void push_compressed_code(v42bis_compress_state_t *ss, int code)/*压缩模式*/
{
ss->output_bit_buffer |= code << (32 - ss->v42bis_parm_c2 - ss->output_bit_count);/*把当前的位存入output_bit_buffer的高位 */
ss->output_bit_count += ss->v42bis_parm_c2; /*输出位计数器增加一个当前码字长度*/
while (ss->output_bit_count >= 8) /*超过8位则按字节输出*/
{
push_compressed_raw_octet(ss, ss->output_bit_buffer >> 24); /*output_bit_buffer把高8位赋值给octet,送出存入到output_buf*/
ss->output_bit_buffer <<= 8; /*??应该是准备输出接下来的8位,但output_bit_buffer上次调用之后值已经变了,不懂*/
ss->output_bit_count -= 8;
}
}
/*- End of function --------------------------------------------------------*/
static __inline__ void push_compressed_octet(v42bis_compress_state_t *ss, int code)/*透明模式*/
{
ss->output_bit_buffer |= code << (32 - 8 - ss->output_bit_count);
ss->output_bit_count += 8;
while (ss->output_bit_count >= 8)
{
push_compressed_raw_octet(ss, ss->output_bit_buffer >> 24);
ss->output_bit_buffer <<= 8;
ss->output_bit_count -= 8;
}
}
/*- End of function --------------------------------------------------------*/
int v42bis_compress(v42bis_state_t *s, const uint8_t *buf, int len)
{
int ptr;
int i;
uint32_t octet;
uint32_t code;
v42bis_compress_state_t *ss;
ss = &s->compress; /*??*/
if ((s->v42bis_parm_p0 & 2) == 0)
{
/* Compression is off - just push the incoming data out */
for (i = 0; i < len - ss->max_len; i += ss->max_len) /*! max_len, brief The maximum frame length allowed */
ss->handler(ss->user_data, buf + i, ss->max_len);
if (i < len)
ss->handler(ss->user_data, buf + i, len - i);
return 0;
}
ptr = 0;
if (ss->first && len > 0)/*! first, brief Mark that this is the first octet/code to be processed */
{
octet = buf[ptr++]; /*读入第一个字符*/
ss->string_code = octet + V42BIS_N6; /*当前前缀为第一个字符对应的码字*/
if (ss->transparent)
push_compressed_octet(ss, octet); /*透明模式则把第一个字符直接发出去。。。两个ss有区别??*/
ss->first = FALSE; /*??*/
}
while (ptr < len) /*len指输入字符流长度*/
{
octet = buf[ptr++]; /*再读入一个字符*/
if ((ss->dict[ss->string_code].children[octet >> 5] & (1 << (octet & 0x1F))))
{
/* The leaf exists. Now find it in the table. */
/* TODO: This is a brute force scan for a match. We need something better. */
for (code = 0; code < ss->v42bis_parm_c3; code++)
{
if (ss->dict[code].parent_code == ss->string_code && ss->dict[code].node_octet == octet)/*当前前缀码字和父节点码字相同,且当前字符跟*/
break;
}
}
else
{
/* The leaf does not exist. */
code = s->v42bis_parm_n2; /*使code>=C3,直接执行else*/
}
/* 6.3(b) If the string matches a dictionary entry, and the entry is not that entry
created by the last invocation of the string matching procedure, then the
next character shall be read and appended to the string and this step
repeated. */
if (code < ss->v42bis_parm_c3 && code != ss->latest_code)
{
/* The string was found */
ss->string_code = code;/*string_code:缀-符串的前缀的码字,code:当前搜到的结点的码字*/
ss->string_length++;
}
else
{
/* The string is not in the table. */
if (!ss->transparent)
{
/* 7.4 Encoding - we now have the longest matchable string, and will need to output the code for it. */
while (ss->v42bis_parm_c1 >= ss->v42bis_parm_c3 && ss->v42bis_parm_c3 <= s->v42bis_parm_n2)
{
/* We need to increase the codeword size */
/* 7.4(a) */
push_compressed_code(ss, V42BIS_STEPUP);/*发命令码字,修改码字的长度*/
/* 7.4(b) */
ss->v42bis_parm_c2++;
/* 7.4(c) */
ss->v42bis_parm_c3 <<= 1;
/* 7.4(d) this might need to be repeated, so we loop */
}
/* 7.5 Transfer - output the last state of the string */
push_compressed_code(ss, ss->string_code);/*输出前缀的码字*/
}
/* 7.6 Dictionary updating */
/* 6.4 Add the string to the dictionary */
/* 6.4(b) The string is not in the table. */
if (code != ss->latest_code && ss->string_length < s->v42bis_parm_n7)
{
ss->latest_code = ss->v42bis_parm_c1;
/* 6.4(a) The length of the string is in range for adding to the dictionary */
/* If the last code was a leaf, it no longer is */
ss->dict[ss->string_code].leaves++;
ss->dict[ss->string_code].children[octet >> 5] |= (1 << (octet & 0x1F));
/* The new one is definitely a leaf */
ss->dict[ss->v42bis_parm_c1].parent_code = (uint16_t) ss->string_code;
ss->dict[ss->v42bis_parm_c1].leaves = 0;
ss->dict[ss->v42bis_parm_c1].node_octet = (uint8_t) octet;
/* 7.7 Node recovery */
/* 6.5 Recovering a dictionary entry to use next */
for (;;)
{
/* 6.5(a) and (b) */
if ((int) (++ss->v42bis_parm_c1) >= s->v42bis_parm_n2)
ss->v42bis_parm_c1 = V42BIS_N5;
/* 6.5(c) We need to reuse a leaf node */
if (ss->dict[ss->v42bis_parm_c1].leaves)
continue;
if (ss->dict[ss->v42bis_parm_c1].parent_code == 0xFFFF)
break;
/* 6.5(d) Detach the leaf node from its parent, and re-use it */
/* Possibly make the parent a leaf node again */
ss->dict[ss->dict[ss->v42bis_parm_c1].parent_code].leaves--;
ss->dict[ss->dict[ss->v42bis_parm_c1].parent_code].children[ss->dict[ss->v42bis_parm_c1].node_octet >> 5] &= ~(1 << (ss->dict[ss->v42bis_parm_c1].node_octet & 0x1F));
ss->dict[ss
v.42bis.rar_v.42b_v.42bis_v.42bis exe_数据压缩 unix
版权申诉
135 浏览量
2022-09-20
16:28:12
上传
评论
收藏 11KB RAR 举报
朱moyimi
- 粉丝: 64
- 资源: 1万+
最新资源
- TG-2024-05-23-204718255.mp4
- 候志强@181 5428 8938_20240420112107.amr
- spispispispispi
- 实验二:IP协议分析.zip
- 驱动代码驱动代码驱动代码驱动代码
- SVID_20240523_141155_1.mp4
- Code for the complete guide to tkinter tutorial
- 关于百货中心供应链管理系统.zip
- SimpleFolderIcon-master 修改Unity的Project下的文件夹图标
- A python Tkinter widget to display tile based maps
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈