File Annotation

Not logged in
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: #include "stdafx.h"
13b7203622 2011-02-23        kinaba: #include "ArcMsc.h"
13b7203622 2011-02-23        kinaba: #include "NoahApp.h"
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcMsc::header( kiFile& fp, unsigned long* siz, char* ext )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	// 読み出す
13b7203622 2011-02-23        kinaba: 	unsigned char p[14];
13b7203622 2011-02-23        kinaba: 	if( 14!=fp.read(p,14) )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// ヘッダ構造:SZDD芋'3A [ext3rd] [orisiz(dword)]
13b7203622 2011-02-23        kinaba: 	static const unsigned char head[9]={ 0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41 };//="SZDD芋'3A";
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	for( int i=0; i!=9; i++ )
13b7203622 2011-02-23        kinaba: 		if( p[i]!=head[i] )
13b7203622 2011-02-23        kinaba: 			return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( ext )
13b7203622 2011-02-23        kinaba: 		*ext = (char)p[9];
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	DWORD x = p[10]+(p[11]<<8)+(p[12]<<16)+(p[13]<<24);
13b7203622 2011-02-23        kinaba: 	if( siz )
13b7203622 2011-02-23        kinaba: 		*siz=x;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 原理的に、16倍という圧縮率は出ない
13b7203622 2011-02-23        kinaba: 	return (x <= fp.getSize()*16);
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: void CArcMsc::filename( char* oname, const char* ol, char ext )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	// コピー
13b7203622 2011-02-23        kinaba: 	ki_strcpy( oname, ol );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 最後が '_' なら消しておく。
13b7203622 2011-02-23        kinaba: 	bool bIs_=false;
13b7203622 2011-02-23        kinaba: 	for( char* p=oname; *p; p=kiStr::next(p) )
13b7203622 2011-02-23        kinaba: 		bIs_ = (*p=='_');
13b7203622 2011-02-23        kinaba: 	if( bIs_ )
13b7203622 2011-02-23        kinaba: 		*(--p)='\0';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( ext )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// 拡張子復元
13b7203622 2011-02-23        kinaba: 		*p++ = ext;
13b7203622 2011-02-23        kinaba: 		*p   = '\0';
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	else
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		// 拡張子自動補完
13b7203622 2011-02-23        kinaba: 		const char* x = kiPath::ext(oname);
13b7203622 2011-02-23        kinaba: 		if( ki_strlen(x)==2 )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			::CharLower(oname);
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 				 if( 0==ki_strcmp(x,"ex") )(*p++)='e';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"co") )(*p++)='m';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"sc") )(*p++)='r';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"dl") )(*p++)='l';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"oc") )(*p++)='x';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"dr") )(*p++)='v';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"vx") )(*p++)='d';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"38") )(*p++)='6';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"sy") )(*p++)='s';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"cp") )(*p++)='l';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"li") )(*p++)='b';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"tt") )(*p++)='f';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"ch") )(*p++)='m';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"hl") )(*p++)='p';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"cn") )(*p++)='t';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"da") )(*p++)='t';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"tx") )(*p++)='t';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"wr") )(*p++)='i';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"wa") )(*p++)='v';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"mi") )(*p++)='d';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"rm") )(*p++)='i';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"bm") )(*p++)='p';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"rl") )(*p++)='e';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"cu") )(*p++)='r';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"do") )(*p++)='c';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"ic") )(*p++)='o';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"re") )(*p++)='g';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"rt") )(*p++)='f';
13b7203622 2011-02-23        kinaba: 			else if( 0==ki_strcmp(x,"ht") )(*p++)='m';
13b7203622 2011-02-23        kinaba: 			else						   (*p++)='#';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			*p = '\0';
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcMsc::v_check( const kiPath& aname )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	kiFile fp;
13b7203622 2011-02-23        kinaba: 	if( fp.open( aname ) )
13b7203622 2011-02-23        kinaba: 		return header( fp,NULL,NULL );
13b7203622 2011-02-23        kinaba: 	return false;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcMsc::v_list( const arcname& aname, aflArray& files )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	kiPath fname(aname.basedir); fname+=aname.lname;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	arcfile x;
13b7203622 2011-02-23        kinaba: 	kiFile fp;
13b7203622 2011-02-23        kinaba: 	char ext;
13b7203622 2011-02-23        kinaba: 	if( !fp.open( fname ) || !header( fp, &x.inf.dwOriginalSize, &ext ) )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 	ki_strcpy( x.inf.szMode, "-msc-" );
13b7203622 2011-02-23        kinaba: 	filename( x.inf.szFileName, aname.lname, ext );
13b7203622 2011-02-23        kinaba: 	x.inf.dwCompressedSize = fp.getSize();
13b7203622 2011-02-23        kinaba: 	x.isfile = true;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// TODO: 日時をどうする?
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	files.add( x );
13b7203622 2011-02-23        kinaba: 	return true;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: int CArcMsc::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	kiFile fp;
13b7203622 2011-02-23        kinaba: 	kiPath fname(aname.basedir); fname+=aname.lname;
13b7203622 2011-02-23        kinaba: 	kiPath oname(ddir);
13b7203622 2011-02-23        kinaba: 	char tmp[MAX_PATH];
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// ヘッダ読み込み
13b7203622 2011-02-23        kinaba: 	char ext;
13b7203622 2011-02-23        kinaba: 	unsigned long alllen;
13b7203622 2011-02-23        kinaba: 	if( !fp.open( fname ) || !header(fp,&alllen,&ext) )
13b7203622 2011-02-23        kinaba: 		return 0xffff;
13b7203622 2011-02-23        kinaba: 	fp.close();
13b7203622 2011-02-23        kinaba: 	filename( tmp, aname.lname, ext );
13b7203622 2011-02-23        kinaba: 	oname += tmp;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 書庫・出力先を開く
13b7203622 2011-02-23        kinaba: 	OFSTRUCT of;
13b7203622 2011-02-23        kinaba: 	of.cBytes = sizeof(of);
13b7203622 2011-02-23        kinaba: 	int FROM = ::LZOpenFile( const_cast<char*>((const char*)fname),&of,OF_READ );
13b7203622 2011-02-23        kinaba: 	int TO   = ::LZOpenFile( const_cast<char*>((const char*)oname),&of,OF_WRITE|OF_CREATE );
13b7203622 2011-02-23        kinaba: 	if( FROM<0 || TO<0 )
13b7203622 2011-02-23        kinaba: 		return 0xffff;
13b7203622 2011-02-23        kinaba: 	// 解凍
13b7203622 2011-02-23        kinaba: 	bool ans = (0<=::LZCopy( FROM,TO ));
13b7203622 2011-02-23        kinaba: 	// 終了
13b7203622 2011-02-23        kinaba: 	::LZClose( TO );
13b7203622 2011-02-23        kinaba: 	::LZClose( FROM );
13b7203622 2011-02-23        kinaba: 	return ans?0:0xffff;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: int CArcMsc::v_compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	::SetCurrentDirectory( base );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 元ファイルを開く
13b7203622 2011-02-23        kinaba: 	kiFile in;
13b7203622 2011-02-23        kinaba: 	if( !in.open( files[0].cFileName ) )
13b7203622 2011-02-23        kinaba: 		return 0xffff;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// ヘッダ情報・圧縮先ファイル名
13b7203622 2011-02-23        kinaba: 	char h_Ext3 = '\0';
13b7203622 2011-02-23        kinaba: 	unsigned long h_Len = in.getSize();
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	char aname[MAX_PATH];
13b7203622 2011-02-23        kinaba: 	ki_strcpy( aname, files[0].cFileName );
13b7203622 2011-02-23        kinaba: 	for( char *x=aname, *last=aname; *x; x=kiStr::next(x) )
13b7203622 2011-02-23        kinaba: 		last = x;
13b7203622 2011-02-23        kinaba: 	if( !IsDBCSLeadByte(*last) )
13b7203622 2011-02-23        kinaba: 		h_Ext3=*last;
13b7203622 2011-02-23        kinaba: 	*last = '_', *(last+1) = '\0';
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 圧縮先開く
13b7203622 2011-02-23        kinaba: 	::SetCurrentDirectory( ddir );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 圧縮先を開く
13b7203622 2011-02-23        kinaba: 	kiFile out;
13b7203622 2011-02-23        kinaba: 	if( !out.open( aname, false ) )
13b7203622 2011-02-23        kinaba: 		return 0xffff;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// タイムスタンプコピー
13b7203622 2011-02-23        kinaba: 	FILETIME ct, at, mt;
13b7203622 2011-02-23        kinaba: 	::GetFileTime(in.getHandle(), &ct, &at, &mt);
13b7203622 2011-02-23        kinaba: 	::SetFileTime(out.getHandle(), &ct, &at, &mt);
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// ヘッダ書き込み
13b7203622 2011-02-23        kinaba: 	unsigned char head[14]={ 0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41,(unsigned char)h_Ext3,
13b7203622 2011-02-23        kinaba: 							 (unsigned char)(h_Len&0xff),(unsigned char)((h_Len>>8)&0xff),
13b7203622 2011-02-23        kinaba: 							 (unsigned char)((h_Len>>16)&0xff),(unsigned char)((h_Len>>24)&0xff) };
13b7203622 2011-02-23        kinaba: 	out.write( head, 14 );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 圧縮作業
13b7203622 2011-02-23        kinaba: 	CArcProgressDlg dlg( h_Len, true );
13b7203622 2011-02-23        kinaba: 	dlg.change( files[0].cFileName );
13b7203622 2011-02-23        kinaba: 	if( !do_lzss( in, out, dlg ) )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		out.close();
13b7203622 2011-02-23        kinaba: 		::DeleteFile(aname);
13b7203622 2011-02-23        kinaba: 		return 0x8020;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	return 0;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: //-- 12bit LZSS -----------------------------------------------//
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: #define N 4096 // slide窓のサイズ 2^12 bytes
13b7203622 2011-02-23        kinaba: #define F 18   // 最長一致長 2^(16-12)+2 bytes
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: static unsigned char window[N+F-1];
13b7203622 2011-02-23        kinaba: static int dad[N+1], lson[N+1], rson[N+257];
13b7203622 2011-02-23        kinaba: static int matchpos, matchlen;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: static void init_tree()
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	//-- 木を初期化
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	int i;
13b7203622 2011-02-23        kinaba: 	for( i=N+1; i<=N+256; i++ ) // root: 0x00 -- 0xff
13b7203622 2011-02-23        kinaba: 		rson[i] = N;
13b7203622 2011-02-23        kinaba: 	for( i=0; i<N ; i++ )
13b7203622 2011-02-23        kinaba: 		 dad[i] = N;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: static void insert_node( int r )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	//-- [位置r]から始まる[列str]を木に登録
13b7203622 2011-02-23        kinaba: 	unsigned char* str = window + r;
13b7203622 2011-02-23        kinaba: 	rson[r] = lson[r] = N;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	//-- ついでに一致長・位置も記録する
13b7203622 2011-02-23        kinaba: 	matchlen = 2;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 一文字目でrootを選ぶ
13b7203622 2011-02-23        kinaba: 	int i, p = N+1+str[0], cmp=1;
13b7203622 2011-02-23        kinaba: 	for(; ;)
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		if( cmp >= 0 )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// 右に進む
13b7203622 2011-02-23        kinaba: 			if( rson[p] != N )
13b7203622 2011-02-23        kinaba: 				p = rson[p];
13b7203622 2011-02-23        kinaba: 			// 右にはもうnodeがないのでそこに登録して終了
13b7203622 2011-02-23        kinaba: 			else
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				rson[p] = r;
13b7203622 2011-02-23        kinaba: 				 dad[r] = p;
13b7203622 2011-02-23        kinaba: 				return;
13b7203622 2011-02-23        kinaba: 			}
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 		else
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// 左に進む
13b7203622 2011-02-23        kinaba: 			if( lson[p] != N )
13b7203622 2011-02-23        kinaba: 				p = lson[p];
13b7203622 2011-02-23        kinaba: 			// 左にはもうnodeがないのでそこに登録して終了
13b7203622 2011-02-23        kinaba: 			else
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				lson[p] = r;
13b7203622 2011-02-23        kinaba: 				 dad[r] = p;
13b7203622 2011-02-23        kinaba: 				return;
13b7203622 2011-02-23        kinaba: 			}
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 現在のnodeとstrを比較( i==一致長 )
13b7203622 2011-02-23        kinaba: 		for( i=1; i<F; i++ )
13b7203622 2011-02-23        kinaba: 			if( cmp = str[i] - window[p+i] )
13b7203622 2011-02-23        kinaba: 				break;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 今まで見つけたものの中で最長だったら記憶
13b7203622 2011-02-23        kinaba: 		if( i > matchlen )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			matchpos = p;
13b7203622 2011-02-23        kinaba: 			if( (matchlen=i) == F )
13b7203622 2011-02-23        kinaba: 				break;
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// [位置p]の列と長さFで一致した場合、ここに来る
13b7203622 2011-02-23        kinaba: 	// p の在ったところを r で置き換える
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	 dad[r] =  dad[p];
13b7203622 2011-02-23        kinaba: 	lson[r] = lson[p];
13b7203622 2011-02-23        kinaba: 	rson[r] = rson[p];
13b7203622 2011-02-23        kinaba: 	 dad[lson[p]] = r;
13b7203622 2011-02-23        kinaba: 	 dad[rson[p]] = r;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( rson[dad[p]]==p )
13b7203622 2011-02-23        kinaba: 		rson[dad[p]] = r;
13b7203622 2011-02-23        kinaba: 	else
13b7203622 2011-02-23        kinaba: 		lson[dad[p]] = r;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	dad[p] = N;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: static void delete_node( int p )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	//-- [位置p]の要素を木から削除
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( dad[p] == N ) // 既に木に入ってないのでおしまい
13b7203622 2011-02-23        kinaba: 		return;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	int q;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( rson[p] == N )
13b7203622 2011-02-23        kinaba: 		q = lson[p]; // 唯一の子を上に持ち上げる
13b7203622 2011-02-23        kinaba: 	else if( lson[p] == N )
13b7203622 2011-02-23        kinaba: 		q = rson[p]; // 唯一の子を上に持ち上げる
13b7203622 2011-02-23        kinaba: 	else
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		q = lson[p];
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		if( rson[q] != N )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// 左の枝の最右、つまり自分より一つ小さいnodeを持ち上げる
13b7203622 2011-02-23        kinaba: 			do
13b7203622 2011-02-23        kinaba: 				q = rson[q];
13b7203622 2011-02-23        kinaba: 			while( rson[q] != N );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			rson[dad[q]] = lson[q];
13b7203622 2011-02-23        kinaba: 			dad[lson[q]] = dad[q];
13b7203622 2011-02-23        kinaba: 			lson[q] = lson[p];
13b7203622 2011-02-23        kinaba: 			dad[lson[p]] = q;
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 		rson[q] = rson[p];
13b7203622 2011-02-23        kinaba: 		dad[rson[p]] = q;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	dad[q] = dad[p];
13b7203622 2011-02-23        kinaba: 	if( rson[dad[p]] == p )
13b7203622 2011-02-23        kinaba: 		rson[dad[p]] = q;
13b7203622 2011-02-23        kinaba: 	else
13b7203622 2011-02-23        kinaba: 		lson[dad[p]] = q;
13b7203622 2011-02-23        kinaba: 	dad[p] = N;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: bool CArcMsc::do_lzss( kiFile& in, kiFile& out, CArcProgressDlg& dlg )
13b7203622 2011-02-23        kinaba: {
13b7203622 2011-02-23        kinaba: 	int i, c, len, r, s;
13b7203622 2011-02-23        kinaba: 	unsigned char code[17]={0}, mask=1, codeptr=1;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	s = 2;		// s = データ読込位置
13b7203622 2011-02-23        kinaba: 	r = N - 16;	// r = 木への挿入位置
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// クリア
13b7203622 2011-02-23        kinaba: 	init_tree();
13b7203622 2011-02-23        kinaba: 	ki_memset( window+2, ' ', N-F );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 先頭18bytes入力
13b7203622 2011-02-23        kinaba: 	for( len=0 ; len<F ; len++ )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		if( -1 == (c = in.getc()) )
13b7203622 2011-02-23        kinaba: 			break;
13b7203622 2011-02-23        kinaba: 		window[r+len] = c;
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 	window[0] = window[r+16];
13b7203622 2011-02-23        kinaba: 	window[1] = window[r+17];
13b7203622 2011-02-23        kinaba: 	if( len==0 )
13b7203622 2011-02-23        kinaba: 		return true;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 木へ挿入
13b7203622 2011-02-23        kinaba: 	for( i=F ; i>=0 ; i-- )
13b7203622 2011-02-23        kinaba: 		insert_node( r-i );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// ループ
13b7203622 2011-02-23        kinaba: 	unsigned int total_read=18,prgr_read=0;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	do
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		if( prgr_read > 5000 )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			dlg.change( NULL, total_read+=prgr_read );
13b7203622 2011-02-23        kinaba: 			prgr_read-=5000;
13b7203622 2011-02-23        kinaba: 			if( !dlg.msgloop() )
13b7203622 2011-02-23        kinaba: 			{
13b7203622 2011-02-23        kinaba: 				prgr_read=0xffffffff;
13b7203622 2011-02-23        kinaba: 				break;
13b7203622 2011-02-23        kinaba: 			}
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		if( matchlen > len )
13b7203622 2011-02-23        kinaba: 			matchlen=len;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		if( matchlen < 3 )	// 一致なし
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			matchlen = 1;
13b7203622 2011-02-23        kinaba: 			code[0] |= mask;
13b7203622 2011-02-23        kinaba: 			code[codeptr++] = window[r];
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 		else				// 一致あり
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			// [pos&0xff] [pos&0xf00 | len-3]
13b7203622 2011-02-23        kinaba: 			code[codeptr++] = (unsigned char)matchpos;
13b7203622 2011-02-23        kinaba: 			code[codeptr++] = (unsigned char)(((matchpos>>4)&0xf0) | (matchlen-3));
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		if( (mask<<=1)==0 ) // code が 8Block になっていたら出力
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			out.write( code, codeptr );
13b7203622 2011-02-23        kinaba: 			// コードバッファ初期化
13b7203622 2011-02-23        kinaba: 			code[0] = 0;
13b7203622 2011-02-23        kinaba: 			codeptr = mask = 1;
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// 出力した分読み込む
13b7203622 2011-02-23        kinaba: 		int lastmatchlen = matchlen;
13b7203622 2011-02-23        kinaba: 		for( i=0 ; i<lastmatchlen; i++ )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			if( -1 == (c=in.getc()) )
13b7203622 2011-02-23        kinaba: 				break;
13b7203622 2011-02-23        kinaba: 			prgr_read++;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			// [位置s]に一文字書き込み
13b7203622 2011-02-23        kinaba: 			delete_node( s );
13b7203622 2011-02-23        kinaba: 			window[s] = c;
13b7203622 2011-02-23        kinaba: 			if( s < F-1 ) window[ N+s ] = c;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			s = (s+1) & (N-1); // s++
13b7203622 2011-02-23        kinaba: 			r = (r+1) & (N-1); // r++
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 			// 木に[位置r]のデータを挿入
13b7203622 2011-02-23        kinaba: 			insert_node( r );
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 		// EOF後処理
13b7203622 2011-02-23        kinaba: 		while( i++ < lastmatchlen )
13b7203622 2011-02-23        kinaba: 		{
13b7203622 2011-02-23        kinaba: 			delete_node( s );
13b7203622 2011-02-23        kinaba: 			s = (s+1) & (N-1); // s++
13b7203622 2011-02-23        kinaba: 			r = (r+1) & (N-1); // r++
13b7203622 2011-02-23        kinaba: 			if( --len )
13b7203622 2011-02-23        kinaba: 				insert_node( r );
13b7203622 2011-02-23        kinaba: 		}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	} while( len > 0 );
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	if( prgr_read==0xffffffff )
13b7203622 2011-02-23        kinaba: 		return false;
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	// 8block境界に揃える
13b7203622 2011-02-23        kinaba: 	if( mask != 1 )
13b7203622 2011-02-23        kinaba: 	{
13b7203622 2011-02-23        kinaba: 		while( mask<<=1 )
13b7203622 2011-02-23        kinaba: 			code[codeptr++] = 0;
13b7203622 2011-02-23        kinaba: 		out.write( code, codeptr );
13b7203622 2011-02-23        kinaba: 	}
13b7203622 2011-02-23        kinaba: 
13b7203622 2011-02-23        kinaba: 	return true;
13b7203622 2011-02-23        kinaba: }
13b7203622 2011-02-23        kinaba: