// ハフマン符号表再構築

#include "_jpeglib.h"
#include "jpeg.h"

#define	DEBUG	0
// デバッグモードはx68上でのみ有効

int MakeiHuff(unchar *(*basetbl0),iHUFFMAN ihufftbl[],unchar cnt[])
// ファイル用ハフマンデータからハフマンテーブルを再構築する
// ハフマンコード表はコードの長さ順、コードの大小順に格納される
// 表の見方は、.datを/16してその商が値ビット長さ、余りが０のランレングス
// basetblは処理後のアドレスを返す
// ファイル上ハフマンテーブルは連続でここのサイズは解らないため、連続処理するしかないため
{
int i,num,k,code,si,len;
unchar *basetbl;
	basetbl=*basetbl0;
	
	// 符号長別個数を得る
	num=0;
	for (i=0;i<16;i++) { // 符号長1bit〜16bit
		num+=cnt[i]=(unshort)*basetbl++;
		#if DEBUG>=1
		printf("cnt[%d]=%d\n",i,cnt[i]);
		#endif
	}
	// num=総合計個数
	#if DEBUG>=1
	printf("合計%d個\n",num);
	#endif
	
	// ハフマンコード表に個数を入れ込む
	k=0;
	for (i=0;i<16;i++) { // 符号長0はあり得ないので
		int j;
		for (j=0;j<cnt[i];j++) {
			ihufftbl[k].len=i+1; // 符号長は1〜16
			#if DEBUG>=1
			printf("[%d]=%dbit\n",k,ihufftbl[k].len);
			#endif
			k++;
		}
	}
	
	// 符号表の復元
	// これがハフマンコード表の性質なので、詳しくはそれを知らなければならない。
	k=0;
	code=0b00; // 0b00から開始
	si=ihufftbl[0].len; // 最初の符号の長さ(==cnt[0]とは限らない)
	while (1) {
		while ((len=ihufftbl[k].len)==si) { // 同一符号長さの中で
			ihufftbl[k].code=code++; // 同一長さ内では＋１づつされていく
			ihufftbl[k].dat=*basetbl++; // そのハフマンコードに対応する数値
			#if DEBUG>=1
			{
			unchar mes[96];
			sprintf(mes,"code=0b%%0%db,%%d:%%d\n",len);
			printf(mes,ihufftbl[k].code,len,ihufftbl[k].dat);
			}
			#endif
			k++;
		}
		// 次の長さの符号へ
		if (k>=num) break; // 全て作り終えた
		do {
			si++;		// 長さ＋１
			code<<=1;	// 符号長が１ビット増える
		} while (len!=si);	// しかし、次の符号長が使われていない時は飛ばす
	}
	*basetbl0=basetbl;
	return(num);
}
