libWJLErrRecoverCoderV1.0.1版本源代码,欢迎专业人士测试。郑重提醒:未经授权,严禁商用
libWJLErrRecoverCoderV1.0.1算法的C源码:
源代码包括了WJLDefine.h、libWJLErrRecoveryCoder.h、WJLErrRecoveryDecode.h、WJLErrRecoveryEncode.h、WJLErrRecoveryCoder.c、WJLErrRecoveryDecode.c、WJLErrRecoveryEncode.c,共7个文件欢迎测试。本次的代码主要是基于《加权概率模型的检错纠错码》设计,根据理论推导码率为
码率虽低,检错效率可达100%,本次公布源代码也是为了方便专业人士验证杰林码的理论完备性,这里使用的是理论中的方法二,符号1和符号0的编码概率分别为
,显然
,所以也不是归一化条件下的概率模型,详细请参看理论推导。当p(0)趋近于1/2,
码率就趋近于1,不过需要对当前的c源进行简单的修改。
(1)WJLDefine.h
/********************************************************************************************
*理论来源:王杰林 -《加权概率模型理论》 *
********************************************************************************************/
#ifndef _WJLDEFINE_H
#define _WJLDEFINE_H
#include "stdlib.h"
#include "math.h"
typedef enum
{
KEEPBACK_NULL = 0, // 前面无符号
KEEPBACK_ZERO, // 前面有符号0
KEEPBACK_ONE, // 前面有符号1
KEEPBACK_ONEZERO // 前面有符号1和符号0
}KEEPBACK_SYMBOL;
// 核心编码器
typedef struct
{
unsigned int RC_SHIFT_BITS; // 低位移去位长
unsigned int RC_MAX_RANGE; // 区间范围最大值
unsigned int RC_MIN_RANGE; // 区间范围最小值
unsigned char *in_buff;
unsigned char *out_buff; // 输出缓存器,仅针对字节
unsigned int out_buff_size; // 循环指针
// 区间:c,(d,n),[L",H]
unsigned int FLow; // 当前区间的下沿(L")
unsigned int FRange; // 当前区间范围(R)
unsigned int FDigits; // 编码时用来保存延迟数字(d)
unsigned int FFollow; // 延迟数字长度(n)
double dzerochange; // 符号0的概率
double donechange; // 符号1的概率
}WJL_ERRRECOVERY_ENCODER;
// 核心解码器
typedef struct
{
unsigned int RC_SHIFT_BITS; // 低位移去位长
unsigned int RC_MAX_RANGE; // 区间范围最大值
unsigned int RC_MIN_RANGE; // 区间范围最小值
unsigned char *out_buff; // 输出缓存器,仅针对字节
unsigned int out_buff_size; // 已输出长度
unsigned char *in_buff;
unsigned int in_buff_rest; // 输入缓存剩余字节
unsigned int in_buff_pos; // 输入缓存当前位置
// 区间:c,(d,n),[L",H]
unsigned int FLow; // 当前区间的下沿(L")
unsigned int FRange; // 当前区间范围(R)
unsigned int Values; // 解码时用来保存输入编码(V)
unsigned char mask;
unsigned char outByte;
double dzerochange; // 符号0的概率
double donechange; // 符号1的概率
KEEPBACK_SYMBOL keepBackSymbol;
}WJL_ERRRECOVERY_DECODER;
// 编码器
typedef struct
{
unsigned int Values; // 解码时用来保存输入编码(V)
unsigned int FLow; // 当前区间的下沿(L")
unsigned int FRange; // 当前区间范围(R)
unsigned int out_buff_size; // 循环指针
unsigned int in_buff_rest; // 输入缓存剩余字节
unsigned char mask;
unsigned int in_buff_pos; // 输入缓存当前位置
KEEPBACK_SYMBOL keepBackSymbol;
}TEMP_Values;
// 每个字节中各位置的比特值
extern const unsigned char bitOfByteTable[256][8];
extern const unsigned int powoftwo[32];
#endif
(2)libWJLErrRecoveryCoder.h
/**************************王杰林扩展模型一阶系数检错技术编解码SDK***************************
*理论来源:王杰林 -《加权概率模型过程理论》 *
*功能:1.58分之一的码率,在发现错误后结束检错过程,并通知出错,如全程无错则解码出原数据 *
*版本:V1.0.1 *
*time:2020.04.27 *
********************************************************************************************/
#ifndef _LIBWJLERRRECOVERYCODER_H
#define _LIBWJLERRRECOVERYCODER_H
#ifdef __cplusplus
extern "C" {
#endif
/****************************************编码(内存->内存)************************************
*输入参数ucInBuffer:原串缓冲首字节地址 *
*输入参数unInbufferLen:原串缓冲字节长度 *
*输出参数unOutbufferLen:编码后的数据缓冲字节长度 *
*返回值:非NULL:编码后的数据缓冲首字节地址,NULL:编码失败 *
********************************************************************************************/
unsigned char *WJL_ErrRecovery_Encode_Buff(unsigned char *ucInBuffer,const unsigned int *unInbufferLen,unsigned int *unOutbufferLen);
/****************************************解码(内存->内存)************************************
*输入参数ucInBuffer:编码串缓冲首字节地址 *
*输入参数unInbufferLen:编码串缓冲字节长度 *
*输入参数unOutbufferLen:原串字节长度 *
*输出参数unPosErr:无法解码后请求重传13字节的第一个字节的地址 *
*返回值:非NULL:解码后的数据缓冲首字节地址,NULL:解码失败 *
********************************************************************************************/
unsigned char *WJL_ErrRecovery_Decode_Buff(unsigned char *ucInBuffer,const unsigned int *unInbufferLen,unsigned int *unOutbufferLen,unsigned int *unPosErr);
#ifdef __cplusplus
}
#endif
#endif
(3)WJLErrRecoveryEncode.h
/********************************************************************************************
*理论来源:王杰林 -《加权概率模型理论》 *
********************************************************************************************/
#ifndef _WJLERRRECOVERYENCODE_H
#define _WJLERRRECOVERYENCODE_H
#include "WJLDefine.h"
//初始化编码器
void Encode_Init(WJL_ERRRECOVERY_ENCODER *erEncoder,const unsigned char *inbuff,const unsigned int *inbufflen);
void Encode_Agent(WJL_ERRRECOVERY_ENCODER *erEncoder,unsigned char *ucInBuffer,const unsigned int *unInbufferLen);
//结束编码过程
void Encode_End(WJL_ERRRECOVERY_ENCODER *erEncoder);
#endif
(4)WJLErrRecoveryDecode.h
/********************************************************************************************
*理论来源:王杰林 -《加权概率模型理论》 *
********************************************************************************************/
#ifndef _WJLERRRECOVERYDECODE_H
#define _WJLERRRECOVERYDECODE_H
#include "WJLDefine.h"
//初始化解码器
void ErrRecovery_Init(WJL_ERRRECOVERY_DECODER *erDecoder,unsigned char *inbuff,const unsigned int *unInfbuffLen);
unsigned char ErrRecovery_Agent(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen,const unsigned int *unInfbuffLen,unsigned int *unPosErr);
void Decode_Init(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen);
void Decode_Agent(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen);
#endif
(5)WJLErrRecoveryCoder.c
#include "libWJLErrRecoveryCoder.h"
#include "WJLErrRecoveryDecode.h"
#include "WJLErrRecoveryEncode.h"
#include "string.h"
#include "stdio.h"
// 每个字节中各位置的比特值
const unsigned char bitOfByteTable[256][8]=
{
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,1},{0,0,0,0,0,0,1,0},{0,0,0,0,0,0,1,1},{0,0,0,0,0,1,0,0},{0,0,0,0,0,1,0,1},{0,0,0,0,0,1,1,0},{0,0,0,0,0,1,1,1}, //0~7
{0,0,0,0,1,0,0,0},{0,0,0,0,1,0,0,1},{0,0,0,0,1,0,1,0},{0,0,0,0,1,0,1,1},{0,0,0,0,1,1,0,0},{0,0,0,0,1,1,0,1},{0,0,0,0,1,1,1,0},{0,0,0,0,1,1,1,1}, //8~15
{0,0,0,1,0,0,0,0},{0,0,0,1,0,0,0,1},{0,0,0,1,0,0,1,0},{0,0,0,1,0,0,1,1},{0,0,0,1,0,1,0,0},{0,0,0,1,0,1,0,1},{0,0,0,1,0,1,1,0},{0,0,0,1,0,1,1,1}, //16~23
{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,1},{0,0,0,1,1,0,1,0},{0,0,0,1,1,0,1,1},{0,0,0,1,1,1,0,0},{0,0,0,1,1,1,0,1},{0,0,0,1,1,1,1,0},{0,0,0,1,1,1,1,1}, //24~31
{0,0,1,0,0,0,0,0},{0,0,1,0,0,0,0,1},{0,0,1,0,0,0,1,0},{0,0,1,0,0,0,1,1},{0,0,1,0,0,1,0,0},{0,0,1,0,0,1,0,1},{0,0,1,0,0,1,1,0},{0,0,1,0,0,1,1,1}, //32~39
{0,0,1,0,1,0,0,0},{0,0,1,0,1,0,0,1},{0,0,1,0,1,0,1,0},{0,0,1,0,1,0,1,1},{0,0,1,0,1,1,0,0},{0,0,1,0,1,1,0,1},{0,0,1,0,1,1,1,0},{0,0,1,0,1,1,1,1}, //40~47
{0,0,1,1,0,0,0,0},{0,0,1,1,0,0,0,1},{0,0,1,1,0,0,1,0},{0,0,1,1,0,0,1,1},{0,0,1,1,0,1,0,0},{0,0,1,1,0,1,0,1},{0,0,1,1,0,1,1,0},{0,0,1,1,0,1,1,1}, //48~55
{0,0,1,1,1,0,0,0},{0,0,1,1,1,0,0,1},{0,0,1,1,1,0,1,0},{0,0,1,1,1,0,1,1},{0,0,1,1,1,1,0,0},{0,0,1,1,1,1,0,1},{0,0,1,1,1,1,1,0},{0,0,1,1,1,1,1,1}, //56~63
{0,1,0,0,0,0,0,0},{0,1,0,0,0,0,0,1},{0,1,0,0,0,0,1,0},{0,1,0,0,0,0,1,1},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,0,1},{0,1,0,0,0,1,1,0},{0,1,0,0,0,1,1,1}, //64~71
{0,1,0,0,1,0,0,0},{0,1,0,0,1,0,0,1},{0,1,0,0,1,0,1,0},{0,1,0,0,1,0,1,1},{0,1,0,0,1,1,0,0},{0,1,0,0,1,1,0,1},{0,1,0,0,1,1,1,0},{0,1,0,0,1,1,1,1}, //72~79
{0,1,0,1,0,0,0,0},{0,1,0,1,0,0,0,1},{0,1,0,1,0,0,1,0},{0,1,0,1,0,0,1,1},{0,1,0,1,0,1,0,0},{0,1,0,1,0,1,0,1},{0,1,0,1,0,1,1,0},{0,1,0,1,0,1,1,1}, //80~87
{0,1,0,1,1,0,0,0},{0,1,0,1,1,0,0,1},{0,1,0,1,1,0,1,0},{0,1,0,1,1,0,1,1},{0,1,0,1,1,1,0,0},{0,1,0,1,1,1,0,1},{0,1,0,1,1,1,1,0},{0,1,0,1,1,1,1,1}, //88~95
{0,1,1,0,0,0,0,0},{0,1,1,0,0,0,0,1},{0,1,1,0,0,0,1,0},{0,1,1,0,0,0,1,1},{0,1,1,0,0,1,0,0},{0,1,1,0,0,1,0,1},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,1}, //96~103
{0,1,1,0,1,0,0,0},{0,1,1,0,1,0,0,1},{0,1,1,0,1,0,1,0},{0,1,1,0,1,0,1,1},{0,1,1,0,1,1,0,0},{0,1,1,0,1,1,0,1},{0,1,1,0,1,1,1,0},{0,1,1,0,1,1,1,1}, //104~111
{0,1,1,1,0,0,0,0},{0,1,1,1,0,0,0,1},{0,1,1,1,0,0,1,0},{0,1,1,1,0,0,1,1},{0,1,1,1,0,1,0,0},{0,1,1,1,0,1,0,1},{0,1,1,1,0,1,1,0},{0,1,1,1,0,1,1,1}, //112~119
{0,1,1,1,1,0,0,0},{0,1,1,1,1,0,0,1},{0,1,1,1,1,0,1,0},{0,1,1,1,1,0,1,1},{0,1,1,1,1,1,0,0},{0,1,1,1,1,1,0,1},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1}, //120~127
{1,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,1},{1,0,0,0,0,0,1,0},{1,0,0,0,0,0,1,1},{1,0,0,0,0,1,0,0},{1,0,0,0,0,1,0,1},{1,0,0,0,0,1,1,0},{1,0,0,0,0,1,1,1}, //128~135
{1,0,0,0,1,0,0,0},{1,0,0,0,1,0,0,1},{1,0,0,0,1,0,1,0},{1,0,0,0,1,0,1,1},{1,0,0,0,1,1,0,0},{1,0,0,0,1,1,0,1},{1,0,0,0,1,1,1,0},{1,0,0,0,1,1,1,1}, //136~143
{1,0,0,1,0,0,0,0},{1,0,0,1,0,0,0,1},{1,0,0,1,0,0,1,0},{1,0,0,1,0,0,1,1},{1,0,0,1,0,1,0,0},{1,0,0,1,0,1,0,1},{1,0,0,1,0,1,1,0},{1,0,0,1,0,1,1,1}, //144~151
{1,0,0,1,1,0,0,0},{1,0,0,1,1,0,0,1},{1,0,0,1,1,0,1,0},{1,0,0,1,1,0,1,1},{1,0,0,1,1,1,0,0},{1,0,0,1,1,1,0,1},{1,0,0,1,1,1,1,0},{1,0,0,1,1,1,1,1}, //152~159
{1,0,1,0,0,0,0,0},{1,0,1,0,0,0,0,1},{1,0,1,0,0,0,1,0},{1,0,1,0,0,0,1,1},{1,0,1,0,0,1,0,0},{1,0,1,0,0,1,0,1},{1,0,1,0,0,1,1,0},{1,0,1,0,0,1,1,1}, //160~167
{1,0,1,0,1,0,0,0},{1,0,1,0,1,0,0,1},{1,0,1,0,1,0,1,0},{1,0,1,0,1,0,1,1},{1,0,1,0,1,1,0,0},{1,0,1,0,1,1,0,1},{1,0,1,0,1,1,1,0},{1,0,1,0,1,1,1,1}, //168~175
{1,0,1,1,0,0,0,0},{1,0,1,1,0,0,0,1},{1,0,1,1,0,0,1,0},{1,0,1,1,0,0,1,1},{1,0,1,1,0,1,0,0},{1,0,1,1,0,1,0,1},{1,0,1,1,0,1,1,0},{1,0,1,1,0,1,1,1}, //176~183
{1,0,1,1,1,0,0,0},{1,0,1,1,1,0,0,1},{1,0,1,1,1,0,1,0},{1,0,1,1,1,0,1,1},{1,0,1,1,1,1,0,0},{1,0,1,1,1,1,0,1},{1,0,1,1,1,1,1,0},{1,0,1,1,1,1,1,1}, //184~191
{1,1,0,0,0,0,0,0},{1,1,0,0,0,0,0,1},{1,1,0,0,0,0,1,0},{1,1,0,0,0,0,1,1},{1,1,0,0,0,1,0,0},{1,1,0,0,0,1,0,1},{1,1,0,0,0,1,1,0},{1,1,0,0,0,1,1,1}, //192~199
{1,1,0,0,1,0,0,0},{1,1,0,0,1,0,0,1},{1,1,0,0,1,0,1,0},{1,1,0,0,1,0,1,1},{1,1,0,0,1,1,0,0},{1,1,0,0,1,1,0,1},{1,1,0,0,1,1,1,0},{1,1,0,0,1,1,1,1}, //200~207
{1,1,0,1,0,0,0,0},{1,1,0,1,0,0,0,1},{1,1,0,1,0,0,1,0},{1,1,0,1,0,0,1,1},{1,1,0,1,0,1,0,0},{1,1,0,1,0,1,0,1},{1,1,0,1,0,1,1,0},{1,1,0,1,0,1,1,1}, //208~215
{1,1,0,1,1,0,0,0},{1,1,0,1,1,0,0,1},{1,1,0,1,1,0,1,0},{1,1,0,1,1,0,1,1},{1,1,0,1,1,1,0,0},{1,1,0,1,1,1,0,1},{1,1,0,1,1,1,1,0},{1,1,0,1,1,1,1,1}, //216~223
{1,1,1,0,0,0,0,0},{1,1,1,0,0,0,0,1},{1,1,1,0,0,0,1,0},{1,1,1,0,0,0,1,1},{1,1,1,0,0,1,0,0},{1,1,1,0,0,1,0,1},{1,1,1,0,0,1,1,0},{1,1,1,0,0,1,1,1}, //224~231
{1,1,1,0,1,0,0,0},{1,1,1,0,1,0,0,1},{1,1,1,0,1,0,1,0},{1,1,1,0,1,0,1,1},{1,1,1,0,1,1,0,0},{1,1,1,0,1,1,0,1},{1,1,1,0,1,1,1,0},{1,1,1,0,1,1,1,1}, //232~239
{1,1,1,1,0,0,0,0},{1,1,1,1,0,0,0,1},{1,1,1,1,0,0,1,0},{1,1,1,1,0,0,1,1},{1,1,1,1,0,1,0,0},{1,1,1,1,0,1,0,1},{1,1,1,1,0,1,1,0},{1,1,1,1,0,1,1,1}, //240~247
{1,1,1,1,1,0,0,0},{1,1,1,1,1,0,0,1},{1,1,1,1,1,0,1,0},{1,1,1,1,1,0,1,1},{1,1,1,1,1,1,0,0},{1,1,1,1,1,1,0,1},{1,1,1,1,1,1,1,0},{1,1,1,1,1,1,1,1} //248~255
};
const unsigned int powoftwo[32] =
{
0x00000001,0x00000002,0x00000004,0x00000008,0x00000010,0x00000020,0x00000040,0x00000080,
0x00000100,0x00000200,0x00000400,0x00000800,0x00001000,0x00002000,0x00004000,0x00008000,
0x00010000,0x00020000,0x00040000,0x00080000,0x00100000,0x00200000,0x00400000,0x00800000,
0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000,0x40000000,0x80000000,
};
//--------------------------------------------------------------------------------------------------------------------------
unsigned char *WJL_ErrRecovery_Encode_Buff(unsigned char *ucInBuffer,const unsigned int *unInbufferLen,unsigned int *unOutbufferLen)
{
WJL_ERRRECOVERY_ENCODER erEncoder;
Encode_Init(&erEncoder,ucInBuffer,unInbufferLen);
Encode_Agent(&erEncoder,ucInBuffer,unInbufferLen);
Encode_End(&erEncoder);
*unOutbufferLen = erEncoder.out_buff_size + sizeof(unsigned int);
erEncoder.out_buff = (unsigned char*)realloc(erEncoder.out_buff,*unOutbufferLen);
memcpy(erEncoder.out_buff+erEncoder.out_buff_size,unInbufferLen,sizeof(unsigned int)); // 存原始串的字节长度
return erEncoder.out_buff;
}
//--------------------------------------------------------------------------------------------------------------------------
unsigned char *WJL_ErrRecovery_Decode_Buff(unsigned char *ucInBuffer,const unsigned int *unInbufferLen,unsigned int *unOutbufferLen,unsigned int *unPosErr)
{
WJL_ERRRECOVERY_DECODER erDecoder;
unsigned int unZipBuffLen = *unInbufferLen - sizeof(unsigned int);
memcpy(unOutbufferLen,ucInBuffer+unZipBuffLen,sizeof(unsigned int)); // 取原始串的字节长度
ErrRecovery_Init(&erDecoder,ucInBuffer,&unZipBuffLen);
if (0x00 == ErrRecovery_Agent(&erDecoder,unOutbufferLen,&unZipBuffLen,unPosErr)) // 查错
{
Decode_Init(&erDecoder,unOutbufferLen);
Decode_Agent(&erDecoder,unOutbufferLen); // 解码
return erDecoder.out_buff;
}
free(erDecoder.out_buff);
return NULL;
}
(6)WJLErrRecoveryEncode.c
#include "WJLErrRecoveryEncode.h"
//--------------------------------------------------------------------------------------------------------------------
void Encode_Init(WJL_ERRRECOVERY_ENCODER *erEncoder,const unsigned char *inbuff,const unsigned int *inbufflen)
{
erEncoder->RC_SHIFT_BITS = 23;
erEncoder->RC_MIN_RANGE = 1<<erEncoder->RC_SHIFT_BITS;
erEncoder->RC_MAX_RANGE = 1<<31;
erEncoder->donechange = 1.0;
erEncoder->dzerochange = 1/3.0; // 1/1.58496250072115618码率
erEncoder->in_buff = (unsigned char*)inbuff;
erEncoder->out_buff_size = 0;
//构建一个比inbufflen长一点的缓存空间
erEncoder->out_buff = (unsigned char*)malloc(*inbufflen*(-log(erEncoder->dzerochange)/log(2.0))+100);
erEncoder->FLow = erEncoder->RC_MAX_RANGE;
erEncoder->FRange = erEncoder->RC_MAX_RANGE;
erEncoder->FDigits = 0;
erEncoder->FFollow = 0;
}
//--------------------------------------------------------------------------------------------------------------------
//更新区间
void Encode_UpdateRange(WJL_ERRRECOVERY_ENCODER *erEncoder,const unsigned char *symbol)
{
unsigned int i,High;
if (1 == *symbol)
{
erEncoder->FLow += (unsigned int)(erEncoder->FRange*erEncoder->dzerochange);
return;
}
erEncoder->FRange *= erEncoder->dzerochange; // 计算当前符号对应的区间宽度
// 区间值小于规定区间的最小值,就需要调整区间
if(erEncoder->FRange<=erEncoder->RC_MIN_RANGE)
{
High = erEncoder->FLow + erEncoder->FRange-1; // 计算出新的区间上沿
if(erEncoder->FFollow!=0) // 判断上一次区间调整时,是否有延迟数字
{
if (High <= erEncoder->RC_MAX_RANGE)
{// 趋向下沿
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FDigits;
for (i = 1; i <= erEncoder->FFollow - 1; i++)
{
erEncoder->out_buff[erEncoder->out_buff_size++] = 0xFF;
}
erEncoder->FFollow = 0; // 重设延迟长度为0
erEncoder->FLow += erEncoder->RC_MAX_RANGE; // 将区间向正数平移
}
else if (erEncoder->FLow >= erEncoder->RC_MAX_RANGE)
{// 趋向上沿
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FDigits + 1;
for (i = 1; i <= erEncoder->FFollow - 1; i++)
{
erEncoder->out_buff[erEncoder->out_buff_size++] = 0x00;
}
erEncoder->FFollow = 0; // 重设延迟长度为0
}
else// 趋向未定
{
erEncoder->FFollow++;
erEncoder->FLow = (erEncoder->FLow << 8) & (erEncoder->RC_MAX_RANGE - 1); // 扩展区间RC_MAX_RANGE - 1得到的是1个0后面31个1,进行与运算就使得FLow的最高位被抹去
erEncoder->FRange <<= 8;
return;
}
}
// 判断最高位数字,^是异或运算,方便提取数据
// FLow ^ High 表示二进制数值进行异或运算,如果FLow和High高8位值是相同的那么就一定会等于00000000
if (((erEncoder->FLow ^ High) & (0xFF << erEncoder->RC_SHIFT_BITS)) == 0)
{
// 出现不变数字,FLow >> RC_SHIFT_BITS+1
// 右移动23位,最终得到高8位的值,由于这里得到的数据要比实际数据大2倍,所以在解码的时候将这里需要右移动一位
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FLow>>erEncoder->RC_SHIFT_BITS;
}
else
{
// 出现延迟数字,首先减去区间最大上沿,有可能是个负数,但是由于FLow被定义为是无符号整型数据,所以会舍弃最高位的符号标识符,这样做等于就是进行取模处理
erEncoder->FLow -= erEncoder->RC_MAX_RANGE;
// FLow >> RC_SHIFT_BITS,右移动23位,得到最高8位的值进行缓存
erEncoder->FDigits = erEncoder->FLow >> erEncoder->RC_SHIFT_BITS;
// 这个时候延迟长度就为1了
erEncoder->FFollow = 1;
}
// 扩展区间RC_MAX_RANGE - 1表示31个1第31位是0,(FLow << 8 ) & ( RC_MAX_RANGE -1 )意思是向左提高倍数后去掉最高位
// FLow & RC_MAX_RANGE得到的是原来FLow的最高位,再进行或处理就是相加了
erEncoder->FLow = (erEncoder->FLow << 8) & (erEncoder->RC_MAX_RANGE - 1);
// 区间就直接扩展256倍
erEncoder->FRange <<= 8;
}
}
//--------------------------------------------------------------------------------------------------------------------
void Encode_Agent(WJL_ERRRECOVERY_ENCODER *erEncoder,unsigned char *ucInBuffer,const unsigned int *unInbufferLen)
{
unsigned int i,j;
unsigned char symbol;
for (i=0;i<*unInbufferLen;++i)
{
for (j=0;j<8;j++)
{
//预处理:0->101,1->01
symbol = bitOfByteTable[ucInBuffer[i]][j];
if (0x00 == symbol)
{
symbol = 0x01;
Encode_UpdateRange(erEncoder,&symbol);
}
symbol = 0x00;
Encode_UpdateRange(erEncoder,&symbol);
symbol = 0x01;
Encode_UpdateRange(erEncoder,&symbol);
}
}
}
//--------------------------------------------------------------------------------------------------------------------
//结束编码过程
void Encode_End(WJL_ERRRECOVERY_ENCODER *erEncoder)
{
unsigned int n = 0;
// 输出剩余延迟数字
if (erEncoder->FFollow != 0)
{
if (erEncoder->FLow < erEncoder->RC_MAX_RANGE)
{// 趋向下沿
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FDigits;
for (n = 1; n <= erEncoder->FFollow - 1; n++)
{
erEncoder->out_buff[erEncoder->out_buff_size++] = 0xFF;
}
}
else
{// 趋向上沿
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FDigits + 1;
for (n = 1; n <= erEncoder->FFollow - 1; n++)
{
erEncoder->out_buff[erEncoder->out_buff_size++] = 0x00;
}
}
}
// 输出剩余编码
erEncoder->FLow = erEncoder->FLow << 1;
n = sizeof(unsigned int)*8;// 32位
do{
n -= 8;// 每次减少8位
erEncoder->out_buff[erEncoder->out_buff_size++] = erEncoder->FLow >> n;// 将高8位输出,第一次就是向右移动24位,剩下高8位,这里做到的是将最后的那int个数字进行处理
} while ( n > 0 );
}
(7)WJLErrRecoveryDecode.c
#include "WJLErrRecoveryDecode.h"
#include "string.h"
//--------------------------------------------------------------------------------------------------------------------
void ErrRecovery_Init(WJL_ERRRECOVERY_DECODER *erDecoder,unsigned char *inbuff,const unsigned int *unInfbuffLen)
{
int n = sizeof(unsigned int)*8;// 32位
erDecoder->RC_SHIFT_BITS = 23;
erDecoder->RC_MIN_RANGE = 1<<erDecoder->RC_SHIFT_BITS;
erDecoder->RC_MAX_RANGE = 1<<31;
erDecoder->FLow = 0;
erDecoder->FRange = erDecoder->RC_MAX_RANGE;// 当前的区间
erDecoder->donechange = 1.0;
erDecoder->dzerochange = 1/3.0;
erDecoder->out_buff = NULL;
erDecoder->out_buff_size = 0;
erDecoder->in_buff = inbuff;
erDecoder->in_buff_rest = *unInfbuffLen;
erDecoder->in_buff_pos = 0;
do{
n -= 8;
erDecoder->Values = (erDecoder->Values << 8) | erDecoder->in_buff[erDecoder->in_buff_pos++];// 左移动8位后,将低8位补齐,再从inbuff中取8位补进来
erDecoder->in_buff_rest--;
} while(n>0);
erDecoder->mask = 0x01;
erDecoder->outByte = 0x00;
erDecoder->keepBackSymbol = KEEPBACK_NULL;
}
//--------------------------------------------------------------------------------------------------------------------
//根据V值比对0区间的H值得出符号
unsigned char Decode_GetSymbol(WJL_ERRRECOVERY_DECODER *erDecoder,unsigned char *ucAppearErr,unsigned char isCheckErr)
{
unsigned char symbol;
unsigned int H0 = erDecoder->FLow,values = erDecoder->Values >> 1;
if (values < erDecoder->FLow)
{
values += erDecoder->RC_MAX_RANGE;
}
H0 += (unsigned int)(erDecoder->FRange*erDecoder->dzerochange);
symbol = values<H0?0:1;
if (KEEPBACK_NULL == erDecoder->keepBackSymbol)
{// 暂存
erDecoder->keepBackSymbol = (0x00==symbol?KEEPBACK_ZERO:KEEPBACK_ONE);
}
else if (KEEPBACK_ZERO == erDecoder->keepBackSymbol)
{
if (0x00 == symbol)
{// 左边界出现00:出现误码,报错
*ucAppearErr = 0x01;
}
else
{// 对01的处理办法:输出1
erDecoder->mask <<= 1;
if (0x00 == isCheckErr)
{
erDecoder->outByte <<= 1;
erDecoder->outByte |= 0x01;
}
if (0x00 == erDecoder->mask)
{
if (0x00 == isCheckErr)
{
erDecoder->out_buff[erDecoder->out_buff_size] = erDecoder->outByte;
erDecoder->outByte = 0x00;
}
erDecoder->out_buff_size++;
erDecoder->mask = 0x01;
}
erDecoder->keepBackSymbol = KEEPBACK_NULL;
}
}
else if (KEEPBACK_ONE == erDecoder->keepBackSymbol)
{
if (0x00 == symbol)
{// 对10的处理办法:保留10
erDecoder->keepBackSymbol = KEEPBACK_ONEZERO;
}
else
{// 左边界出现11:出现误码,报错
*ucAppearErr = 0x01;
}
}
else
{
if (0x00 == symbol)
{// 左边界出现100:出现误码,报错
*ucAppearErr = 0x01;
}
else
{// 对101的处理办法:输出0
erDecoder->mask <<= 1;
if (0x00 == isCheckErr)
{
erDecoder->outByte <<= 1;
}
if (0x00 == erDecoder->mask)
{
if (0x00 == isCheckErr)
{
erDecoder->out_buff[erDecoder->out_buff_size] = erDecoder->outByte;
erDecoder->outByte = 0x00;
}
erDecoder->out_buff_size++;
erDecoder->mask = 0x01;
}
erDecoder->keepBackSymbol = KEEPBACK_NULL;
}
}
return symbol;
}
//--------------------------------------------------------------------------------------------------------------------
// 更新区间
unsigned char Decode_UpdateRange(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned char *symbol)
{
if (1 == *symbol)
{
erDecoder->FLow += (unsigned int)(erDecoder->FRange*erDecoder->dzerochange);
return 0x01;
}
erDecoder->FRange *= erDecoder->dzerochange; // 计算当前符号对应的区间宽度
// 调整区间
if (erDecoder->FRange <= erDecoder->RC_MIN_RANGE)
{
erDecoder->FLow = (erDecoder->FLow << 8) & (erDecoder->RC_MAX_RANGE - 1);
erDecoder->FRange <<= 8;
if (erDecoder->in_buff_rest > 0)
{
erDecoder->Values = (erDecoder->Values << 8) | erDecoder->in_buff[erDecoder->in_buff_pos++];
erDecoder->in_buff_rest --;
}
return 0x00; // 完成了当前v值的检测,并更新了v值
}
return 0x01; // 未完成当前v值的检测
}
//--------------------------------------------------------------------------------------------------------------------------
// 对当前v值进行检错,返回0x00表示v值是对的,返回0x01代表发现了错误
unsigned char Detect_Core(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen)
{
unsigned char symbol,ucAppearErr=0x00;
// 检查v值是否有比特传输错误
while (1)
{
symbol = Decode_GetSymbol(erDecoder,&ucAppearErr,1);
if (erDecoder->out_buff_size == *unOutbufferLen)
{// 结束解码
return 0x00;
}
if (ucAppearErr)
{// 检查不通过
return 0x01;
}
if (0x00 == Decode_UpdateRange(erDecoder,&symbol))
{// v值通过了检查,且更新了v值
return 0x00;
}
}
}
//--------------------------------------------------------------------------------------------------------------------
unsigned char ErrRecovery_Agent(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen,const unsigned int *unInfbuffLen,unsigned int *unPosErr)
{
do
{// 检查当前V值是否有错(通过了检查的话V值会右移8位进行更新,继而对备份的各个V值进行更新)
if (0x01 == Detect_Core(erDecoder,unOutbufferLen))
{// 发现错误
return 0x01;
}
} while (erDecoder->out_buff_size<*unOutbufferLen);
return 0x00;
}
//--------------------------------------------------------------------------------------------------------------------
void Decode_Init(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen)
{
unsigned int n = 32;
erDecoder->out_buff = (unsigned char*)malloc(*unOutbufferLen);
erDecoder->out_buff_size = 0;
erDecoder->in_buff_rest = erDecoder->in_buff_pos;
erDecoder->in_buff_pos = 0;
erDecoder->FLow = 0;
erDecoder->FRange = erDecoder->RC_MAX_RANGE;// 当前的区间
do{
n -= 8;
erDecoder->Values = (erDecoder->Values<<8) | erDecoder->in_buff[erDecoder->in_buff_pos++];// 左移动8位后,将低8位补齐
erDecoder->in_buff_rest--;
} while(n>0);
erDecoder->mask = 0x01;
erDecoder->outByte = 0x00;
erDecoder->keepBackSymbol = KEEPBACK_NULL;
}
//--------------------------------------------------------------------------------------------------------------------
void Decode_Agent(WJL_ERRRECOVERY_DECODER *erDecoder,const unsigned int *unOutbufferLen)
{
unsigned char symbol,ucAppearErr=0x00;
do
{
symbol = Decode_GetSymbol(erDecoder,&ucAppearErr,0);
Decode_UpdateRange(erDecoder,&symbol);
} while (erDecoder->out_buff_size < *unOutbufferLen);
}