/*
 *	cliphfm.h
 *
 *	Canonical Huffman Code
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2016 Naoyuki Sawa
 *
 *	* Fri Nov 21 20:05:45 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	- 下記の記事を参考にしました。
 *	  「高速に符号／復号を行える最小冗長符号「Canonical Huffman Code」」(http://codezine.jp/article/detail/376)
 *	  (ダウンロードして「keep/高速に符号／復号を行える最小冗長符号「Canonical Huffman Code」.7z」に保存しておきました。)
 *	  アルゴリズムは参考にしましたが、サンプルソースの実装はよく理解できなかったので、ほぼ新規に実装しました。
 *	  サンプルソースよりも、当モジュールの実装の方が、デコーダのフットプリントが小さくて、P/ECEに適していると思います。
 *	  また、圧縮時に格納する符号表が小さく済むよう工夫したので、サンプルソースよりも当モジュールの実装の方が、僅かに圧縮率が高いです。
 *	  さらに、サンプルソースは元データのサイズをヘッダに格納していますが、当モジュールは終端符号で判断する点が、優れていると思います。
 *	* Sat Nov 22 10:24:01 JST 2014 Naoyuki Sawa
 *	- 圧縮データの作成は、DOSコマンドラインツール「tool/dphfm」を利用してください。
 *	* Sat Nov 22 14:56:38 JST 2014 Naoyuki Sawa
 *	- HuffmanDecoder_Getc()をアセンブラ化しました。
 *	  HuffmanDecoder_Decode()で、約39KB⇒約62KBの展開を行った時の速度が、約1.106秒⇒約0.790秒に高速化しました。(Clock=48MHz,Code=SRAM,Stack=FRAM)
 *	* Sat Nov 22 16:01:39 JST 2014 Naoyuki Sawa
 *	- HuffmanDecoder_Init()をアセンブラ化しました。
 *	  コードサイズが12バイト小さくなりました。速度にはほとんど影響ありません。
 *	* Sat Nov 22 17:24:18 JST 2014 Naoyuki Sawa
 *	- HuffmanDecoder_Decode()をアセンブラ化しました。
 *	  HuffmanDecoder_Decode()で、約39KB⇒約62KBの展開を行った時の速度が、約0.790秒⇒約0.759秒に高速化しました。(Clock=48MHz,Code=SRAM,Stack=FRAM)
 *	* Sun Nov 23 01:00:09 JST 2014 Naoyuki Sawa
 *	- cliphfm.cから、デコーダー部分をframhfm.cに分離しました。
 *	  P/ECE上ではデコーダーしか使用しないことが多いので、常にエンコーダーがリンクされて容量が増加することを防ぐためです。
 *	  framhfm.cを高速RAMに配置して、高速化することも可能です。
 *	  framhfm.cを高速RAMに配置すると、HuffmanDecoder_Decode()で、約39KB⇒約62KBの展開を行った時の速度が、約0.759秒⇒約0.419秒に高速化しました。(Clock=48MHz,Code=FRAM,Stack=FRAM)
 *	* Sun Nov 23 21:49:53 JST 2014 Naoyuki Sawa
 *	- HuffmanDecoder_Getc()に、「工夫した計算順序」を適用しました。(C言語版とアセンブラ版の両方)
 *	  HuffmanDecoder_Decode()で、約39KB⇒約62KBの展開を行った時の速度が、約0.759秒⇒約0.756秒に高速化しました。(Clock=48MHz,Code=SRAM,Stack=FRAM)
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 *	* Thu Sep 29 21:37:05 JST 2016 Naoyuki Sawa
 *	- Hewではエンコーダーを含めないようにしました。
 */
#ifndef __CLIP_HFM_H__
#define __CLIP_HFM_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

#ifndef __RENESAS__	//{{2016/09/29追加:Hewではエンコーダーを含めないようにしました。}}
/****************************************************************************
 *	ハフマンエンコーダー
 ****************************************************************************/
//全体を一度で圧縮する関数
int HuffmanEncoder_Encode(const void* _src, int srcBytes, void* dst, int dstBytes);
#endif//__RENESAS__	//{{2016/09/29追加:Hewではエンコーダーを含めないようにしました。}}

/****************************************************************************
 *	ハフマンデコーダー
 ****************************************************************************/
//ハフマンデコーダー構造体
typedef struct _ST_HuffmanDecoder {	//アセンブラ版から参照しているのでレイアウト固定です。
	const void*	src;		//+0,4 符号表のアドレス
	int		srcPos;		//+4,4 次に読み出す符号のビット位置	srcからの相対
} ST_HuffmanDecoder;			//=8
/*--------------------------------------------------------------------------*/
//全体を一度で展開する関数
int HuffmanDecoder_Decode(const void* src, void* _dst, int dstBytes);
//１バイトづつ展開する関数(展開ストリーム)
void HuffmanDecoder_Init(ST_HuffmanDecoder* pHuffmanDecoder, const void* src);
int HuffmanDecoder_Getc(ST_HuffmanDecoder* pHuffmanDecoder);

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif//__CLIP_HFM_H__
