/*	
 *	clipzlib.c
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2002 Naoyuki Sawa
 *
 *	* Sat Oct 12 06:07:00 JST 2002 Naoyuki Sawa
 *	- clippce.cからzlib関数だけを分離しました。
 *	  アプリケーションがこれらの関数を使わなければ、
 *	  これらの関数が利用しているzlibライブラリもリンクされないので、
 *	  zlibを使わないアプリケーションのサイズが小さくなるはずです。
 *	* Sun Nov 3 08:32:00 JST 2002 Naoyuki Sawa
 *	- my_compress()を追加しました。
 *	* Mon Nov 26 00:47:00 JST 2002 Naoyuki Sawa
 *	- zlib/unzip.cで、圧縮ファイルの解凍と書庫ファイルの管理ができるようになったので、
 *	  my_compress()以外のZlibユーティリティと、ファイルパックユーティリティをOBSOLATEにしました。
 *	* Wed Feb 26 12:45:00 JST 2003 Naoyuki Sawa
 *	- my_unzip()をclippce.cからclipzlib.cへ移動しました。
 *	  （zlib/zlpを使わないアプリケーションにリンクされてしまうのを防ぐため）
 *	* Wed Feb 27 19:37:00 JST 2003 Naoyuki Sawa
 *	- my_unzip()をclipunz.cへ移しました。
 *	  （my_unzip()を使っただけで、zlib圧縮ルーチンまでリンクされるのを防ぐため）
 */
#include "clip.h"

/****************************************************************************
 *	zlib展開
 ****************************************************************************/

//→2002/11/26: OBSOLETEです。unzipを使ってください。
//int
//file_inflate(FILEACC* fa, void* outbuf, int outlen, int inofs, int inlen)
//{
//#define INBUFSIZ	0x400	/* 入力バッファサイズ(調整可能) */
//
//	int retval, done = 0;
//	z_stream z;
//	unsigned char* inbuf;
//
//	/* 圧縮データサイズが0なら、ファイル終端までと見なします。 */
//	if(inofs < 0 || fa->fsize - 1 < inofs) return 0; /* オフセット不正 */
//	if(inlen == 0) inlen = fa->fsize - inofs;
//	if(inofs + inlen > fa->fsize) return 0; /* 圧縮データサイズ不正 */
//
//	/* 初期化。 */
//	memset(&z, 0, sizeof z);
//	retval = inflateInit(&z);
//	if(retval != Z_OK) return 0; /* 初期化失敗。メモリ不足？ */
//	/* これ以降のエラーは、return 0 ではなく goto ERR です！ */
//
//	/* 入力バッファを確保します。
//	 * next_inで直接フラッシュメモリ上のデータを指すこともできますが、
//	 * まずは動作が確認できるまで、わかり易い方法を採ることにしました。
//	 */
//	inbuf = (unsigned char*)malloc(INBUFSIZ);
//	if(inbuf == NULL) goto ERR; /* メモリ不足 */
//
//	z.next_out = (unsigned char*)outbuf; /* 出力ポインタ     */
//	z.avail_out = outlen;                /* 出力バッファ残量 */
//	for(;;) {
//		if(z.avail_in == 0) {      /* 入力残量がゼロになれば */
//			z.next_in = inbuf; /* 入力ポインタを元に戻す */
//			z.avail_in = file_read(fa, inbuf, inofs, inlen < INBUFSIZ ? inlen : INBUFSIZ); /* データを読む */
//			if(z.avail_in == 0) goto ERR; /* 入力データ不足。壊れている？ */
//			inofs += z.avail_in;
//			inlen -= z.avail_in;
//		}
//		retval = inflate(&z, Z_NO_FLUSH); /* 展開 */
//		if(retval == Z_STREAM_END) { done = 1; break; } /* 完了 */
//		if(retval != Z_OK) goto ERR; /* 入力データ不正。壊れている？ */
//		if(z.avail_out == 0) goto ERR; /* 出力バッファ不足 */
//	}
//
//	/* FALL THRU */
//ERR:
//	/* 後始末。 */
//	retval = inflateEnd(&z);
//	if(retval != Z_OK) done = 0; /* どこかでメモリ壊した？ */
//
//	/* 入力バッファを開放します。
//	 * malloc()に失敗していた場合はinbuf=NULLですが、free(NULL)は安全です。
//	 */
//	free(inbuf);
//
//	/* 成功なら展開後のサイズ、失敗なら0を返します。 */
//	return done ? outlen - z.avail_out : 0;
//
//#undef INBUFSIZ
//}

//→2002/11/26: OBSOLETEです。unzipを使ってください。
///* file_inflate()をコピーしてきて修正して作りました。 */
//int
//file_inflate_size(FILEACC* fa, int inofs, int inlen)
//{
//#define INBUFSIZ	0x400	/* 入力バッファサイズ(調整可能) */
//#define OUTBUFSIZ	0x400	/* 出力バッファサイズ(調整可能) */
//
//	int retval, done = 0, size = 0;
//	z_stream z;
//	unsigned char* inbuf = NULL;  /* エラー処理のため、NULLにしておく */
//	unsigned char* outbuf = NULL; /* エラー処理のため、NULLにしておく */
//
//	/* 圧縮データサイズが0なら、ファイル終端までと見なします。 */
//	if(inofs < 0 || fa->fsize - 1 < inofs) return 0; /* オフセット不正 */
//	if(inlen == 0) inlen = fa->fsize - inofs;
//	if(inofs + inlen > fa->fsize) return 0; /* 圧縮データサイズ不正 */
//
//	/* 初期化。 */
//	memset(&z, 0, sizeof z);
//	retval = inflateInit(&z);
//	if(retval != Z_OK) return 0; /* 初期化失敗。メモリ不足？ */
//	/* これ以降のエラーは、return 0 ではなく goto ERR です！ */
//
//	/* 入出力バッファを確保します。 */
//	inbuf = (unsigned char*)malloc(INBUFSIZ);
//	if(inbuf == NULL) goto ERR; /* メモリ不足 */
//	outbuf = (unsigned char*)malloc(OUTBUFSIZ);
//	if(outbuf == NULL) goto ERR; /* メモリ不足 */
//
//	for(;;) {
//		if(z.avail_in == 0) {      /* 入力残量がゼロになれば */
//			z.next_in = inbuf; /* 入力ポインタを元に戻す */
//			z.avail_in = file_read(fa, inbuf, inofs, inlen < INBUFSIZ ? inlen : INBUFSIZ); /* データを読む */
//			if(z.avail_in == 0) goto ERR; /* 入力データ不足。壊れている？ */
//			inofs += z.avail_in;
//			inlen -= z.avail_in;
//		}
//		z.next_out = outbuf;     /* 出力ポインタは毎回先頭に戻します */
//		z.avail_out = OUTBUFSIZ; /* 出力バッファ残量も同じく戻します */
//		retval = inflate(&z, Z_NO_FLUSH); /* 展開 */
//		size += OUTBUFSIZ - z.avail_out;  /* 出力サイズ加算 */
//		if(retval == Z_STREAM_END) { done = 1; break; } /* 完了 */
//		if(retval != Z_OK) goto ERR; /* 入力データ不正。壊れている？ */
//	}
//
//	/* FALL THRU */
//ERR:
//	/* 後始末。 */
//	retval = inflateEnd(&z);
//	if(retval != Z_OK) done = 0; /* どこかでメモリ壊した？ */
//
//	/* 入出力バッファを開放します。 */
//	free(inbuf);
//	free(outbuf);
//
//	/* 成功なら展開後のサイズ、失敗なら0を返します。 */
//	return done ? size : 0;
//
//#undef INBUFSIZ
//#undef OUTBUFSIZ
//}

//→2002/11/26: OBSOLETEです。unzipを使ってください。
//int
//fpak_inflate(FILEACC* fa, void* outbuf, int outlen, const char* fname)
//{
//	FILE_INFO* fi;
//
//	/* ファイルを探します。 */
//	fi = fpak_find(fa, fname);
//	if(fi == NULL) return 0; /* 見つからなかった */
//
//	/* ファイルを展開します。 */
//	return file_inflate(fa, outbuf, outlen, fi->offset, fi->size);
//}

//→2002/11/26: OBSOLETEです。unzipを使ってください。
//int
//fpak_inflate_size(FILEACC* fa, const char* fname)
//{
//	FILE_INFO* fi;
//
//	/* ファイルを探します。 */
//	fi = fpak_find(fa, fname);
//	if(fi == NULL) return 0; /* 見つからなかった */
//
//	/* ファイルを展開します。 */
//	return file_inflate_size(fa, fi->offset, fi->size);
//}

/* zlib 1.1.4のcompress2関数(compress.c)をコピーして手を加えました。
 * 参考資料：「リブルラブル研究所(http://www001.upp.so-net.ne.jp/LibbleRabble/)」さんの
 *           『P/ECEでリモコン(IrRC)Ver.1.14』のソースを参考にさせて頂きました。
 */
int
my_compress(void* out, int* outlen, const void* in, int inlen)
{
	int retval;
	z_stream z;

	memset(&z, 0, sizeof z);
	z.next_in = (Bytef*)in;
	z.avail_in = (uInt)inlen;
	z.next_out = out;
	z.avail_out = (uInt)*outlen;

	retval = deflateInit2(&z,
		/*Z_DEFAULT_COMPRESSION*/9,	/* 0〜 9(省メモリに関係ないようなので、最大圧縮率に設定しました) */
		Z_DEFLATED,
		/*MAX_WBITS*/9,			/* 8〜15(ここがいちばん圧縮率・メモリ使用量に影響します) */
						/* zlib.hには8..15と書いてありますが、8ではエラーになるようです。 */
		/*MAX_MEM_LEVEL*/1,		/* 1〜 8(最小設定の1でも、テキストなら50〜60%程度にはなります) */
		Z_DEFAULT_STRATEGY);
	if(retval != Z_OK) return retval;

	retval = deflate(&z, Z_FINISH);
	if(retval != Z_STREAM_END) {
		deflateEnd(&z);
		return retval == Z_OK ? Z_BUF_ERROR : retval;
	}
	*outlen = z.total_out;

	return deflateEnd(&z);
}

