/*
 *	clipdrh.h
 *
 *	差分圧縮⇒連長圧縮⇒ハフマン圧縮
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2014 Naoyuki Sawa
 *
 *	* Mon Nov 24 10:36:38 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	- ハフマン圧縮の応用例として、作成しました。
 *	  連続して変化するようなデータを圧縮する際に、ハフマン圧縮だけを単独で使用するよりも圧縮率が良くなります。
 *	  今後、LEDデコーダーで利用することを想定しています。
 *	- 当モジュールで工夫した点は、連長と差分の符号をマージした事です。
 *	  連長と差分は、別々の符号表で圧縮します。(連長と差分の出現値は偏りの傾向が違うので、別々の符号表で圧縮する方が圧縮率が良いと思うから)
 *	  一方、連長と差分の符号並びは分けない方が、次に読み出す符号のビット位置を一つで管理でき、都合が良いです。
 *	  従って、連長と差分の符号が交互に取得できるよう、マージしました。
 *	  確か、一般的な圧縮形式(zipやlzh等)も、そうなっていたと思います。
 *	- 連長圧縮が効かないデータだと、ハフマン圧縮よりも単純に2倍の処理時間がかかります。(連長と差分の復号化を行う必要があるため)
 *	  データの特性によって、圧縮の方式を慎重に選択する必要があります。
 *	* Thu Nov 27 21:49:37 JST 2014 Naoyuki Sawa
 *	- DeltaRunHuffmanDecoder_Decode(),DeltaRunHuffmanDecoder_Init(),DeltaRunHuffmanDecoder_Getc()をアセンブラ化しました。
 *	  DeltaRunHuffmanDecoder_Decode()で、約50KB⇒約64KBの展開を行った時の速度が、約2.237秒⇒約1.487秒に高速化しました。(Clock=48MHz,Code=SRAM,Stack=FRAM)
 *	- まだ、アセンブラ版DeltaRunHuffmanDecoder_Decode(),DeltaRunHuffmanDecoder_Init(),DeltaRunHuffmanDecoder_Getc()の動作確認を、充分に行っていません。	//┐
 *	  引き続き、アセンブラ版DeltaRunHuffmanDecoder_Decode(),DeltaRunHuffmanDecoder_Init(),DeltaRunHuffmanDecoder_Getc()の動作確認を行う予定です。		//※TODO:2014/11/27時点未完了。充分に動作確認したらこのコメントは消せ。
 *	  特に、アセンブラ版DeltaRunHuffmanDecoder_Getc()の動作確認を、重点的に行う必要があります。								//┘
 */
#ifndef __CLIP_DRH_H__
#define __CLIP_DRH_H__

//[note]
//詳細なコメントは省略した。
//アルゴリズムの説明はcliphfm.c,framhfm.cを参照せよ。

/****************************************************************************
 *	差分圧縮⇒連長圧縮⇒ハフマン圧縮エンコーダー
 ****************************************************************************/
//全体を一度で圧縮する関数
int DeltaRunHuffmanEncoder_Encode(const void* _src, int srcBytes, void* _dst, int dstBytes);

/****************************************************************************
 *	差分圧縮⇒連長圧縮⇒ハフマン圧縮デコーダー
 ****************************************************************************/
//差分圧縮⇒連長圧縮⇒ハフマン圧縮デコーダー構造体
typedef struct _ST_DeltaRunHuffmanDecoder {	//アセンブラ版から参照するのでレイアウト固定です。
	const void*		src;		//+ 0,4: 連長の符号表のアドレス						//呼び出し側で保持できる場合は呼び出し側で保持し、DeltaRunHuffmanDecoder_Getc()の呼び出し時のみST_DeltaRunHuffmanDecoderを組み立てよ。
	int			srcPos;		//+ 4,4: 次に読み出す符号のビット位置	srcからの相対
	unsigned char		run;		//+ 8,1: 残りの連長			実質8bit
	unsigned char		delta;		//+ 9,1: 現在の差分			LEDならば実質5bit	3┬───14bit余り
	unsigned char		value;		//+10,1: 現在の値			LEDならば実質5bit	3┤	//この余り部分にLEDデコーダーチェインのNextを入れられる。LEDデコーダーで利用する場合は、都度、構造体を組み立てるようにする予定である。
						//+11,1: パディング			実質0bit		8┘
} ST_DeltaRunHuffmanDecoder;			//=12
/*--------------------------------------------------------------------------*/
//全体を一度で展開する関数
int DeltaRunHuffmanDecoder_Decode(const void* src, void* _dst, int dstBytes);
//１バイトづつ展開する関数(展開ストリーム)
void DeltaRunHuffmanDecoder_Init(ST_DeltaRunHuffmanDecoder* pDeltaRunHuffmanDecoder, const void* src);
int DeltaRunHuffmanDecoder_Getc(ST_DeltaRunHuffmanDecoder* pDeltaRunHuffmanDecoder);

#endif//__CLIP_DRH_H__
