杰林码检错算法1.0.1版本C源码(libWJLErrRecoverCoderV1.0.1)

libWJLErrRecoverCoderV1.0.1版本源代码,欢迎专业人士测试。郑重提醒:未经授权,严禁商用

libWJLErrRecoverCoderV1.0.1算法的C源码:
源代码包括了WJLDefine.h、libWJLErrRecoveryCoder.h、WJLErrRecoveryDecode.h、WJLErrRecoveryEncode.h、WJLErrRecoveryCoder.c、WJLErrRecoveryDecode.c、WJLErrRecoveryEncode.c,共7个文件欢迎测试。本次的代码主要是基于《加权概率模型的检错纠错码》设计,根据理论推导码率为 R = 1 / log 2 ( 1 / 3 ) = 0.63 R=-1/\log_2(1/3)=0.63
码率虽低,检错效率可达100%,本次公布源代码也是为了方便专业人士验证杰林码的理论完备性,这里使用的是理论中的方法二,符号1和符号0的编码概率分别为 p ( 0 ) = 1 / 3 , p ( 1 ) = 1 p(0)=1/3,p(1)=1 ,显然 p ( 0 ) + p ( 1 ) = 1.3333 p(0)+p(1)=1.3333 ,所以也不是归一化条件下的概率模型,详细请参看理论推导。当p(0)趋近于1/2, p ( 1 ) = 1 p(1)=1 码率就趋近于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);
}

原创文章 31 获赞 50 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wjlxueshu/article/details/105806373