/* * Zio.h * EBLib2 * * Created by hishida on 08/12/22. * Copyright 2008 __MyCompanyName__. All rights reserved. * */ // Zio.h: CZio クラスのインターフェイス // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ZIO_H__D5B7C386_75AC_4193_AA99_B326CE9287D3__INCLUDED_) #define AFX_ZIO_H__D5B7C386_75AC_4193_AA99_B326CE9287D3__INCLUDED_ #if defined(_MSC_VER) #ifdef _WIN32_WCE #include "FileIO.h" #else #include #define off_t __int64 #define ftello(a) _telli64(_fileno(a)) int fseeko( FILE *stream, off_t offset, int origin ); #endif #endif #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define _SSED_SUPPORT 1 // LogoVista電子辞典のサポート #define EBZ_HEAD_LEN 22 // ebzip形式のヘッダ長(ヘッダ直後がインデックス) /* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | マジック ID |*1| *2 |ファイルの大きさ | Adler-32 | 修正時刻 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 *1: zip モードと圧縮レベル *2: 予約領域 マジック ID (5 バイト) 0x45, 0x42, 0x5a, 0x69, 0x70 (ASCII 文字列で表すと EBZip) zip モード (MSB 側の 4 ビット) 圧縮モード。 EB ライブラリバージョン 4.0 では、1 (2 進数で 0001) 圧縮レベル (LSB 側の 4 ビット) 予約領域 (2 バイト) 0x0000 ファイルの大きさ (6 バイト) 元の (非圧縮時の) ファイルの大きさを記録 Adler-32 (4 バイト) RFC 1950 のAdler-32 アルゴリズムを用いて計算した、非圧縮データのチェックサムの値 修正時刻 (4 バイト) 元のファイルの最終修正時刻。グリニッジ標準時の 1970 年 1 月 1 日 0 時 0 分 0 秒からの経過秒数 */ // スライスバッファ個数 // maxSliceの設定値; pSliceのバッファ個数になる // 注意:修正する場合、MAX_EPW_BUF が最大になるように #if defined(_WIN32_WCE) && !defined(USE_CE64BIT) || !defined(_MSC_VER) #define MAX_SLICE_BUF 2 // ebzip #define MAX_SSED_BUF 2 // LogoVista #define MAX_SEBXA_BUF 2 // S-EBXA #define MAX_EPW_BUF 16 // EPWING圧縮形式 #else #define MAX_SLICE_BUF 16 // ebzip #define MAX_SSED_BUF 16 // LogoVista #define MAX_SEBXA_BUF 16 // S-EBXA #define MAX_EPW_BUF 16 // EPWING圧縮形式 // 高速化のためのインデックス表常駐の有無 #define USE_SEBXA_RESIDENT_INDEX 1 // S-EBXA用常駐インデックスの使用 #define USE_SSED_RESIDENT_INDEX 1 // LogoVista用常駐インデックスの使用 #define USE_EBZIP_RESIDENT_INDEX 1 // ebzip用常駐インデックスの使用 #endif // スライスバッファサイズ(ebzipは圧縮レベルによって異なる) #define EPW_SLICE_SIZE 2048 #define SEBXA_SLICE_SIZE 4096 #define SSED_SLICE_SIZE 32768 // 圧縮形式 #define COMP_NONE 0 // 非圧縮 #define COMP_EBZIP 1 // ebzip #define COMP_SSED 2 // LogoVista電子辞典 #define COMP_EPV4 3 // EPWING V4 #define COMP_EPV6 4 // EPWING V6 #define COMP_SEBXA 5 // S-EBXA 圧縮形式 // EPWING圧縮のハフマン木のノードタイプ #define NODE_EOD 0 /* 葉ノード(終端値) */ #define NODE_LEAF8 1 /* 葉ノード(8ビット値) */ #define NODE_LEAF16 2 /* 葉ノード(16ビット値) */ #define NODE_LEAF32 3 /* 葉ノード(32ビット値) */ #define NODE_INT 4 /* 中間ノード */ ; // EPWING 圧縮ヘッダ typedef struct { size_t idxOffs; // 圧縮インデックスの開始位置 int idxLen; // 圧縮インデックスの長さ size_t freqOffs; // 頻度テーブルの開始位置 int freqLen; // 頻度テーブルの長さ size_t honbun; // 本文の開始位置 } CompHdr; // ハフマン木ノード typedef struct treeNode_t { int left; // 左子ノード int right; // 右子ノード int freq; // 頻度値; =0なら親ノードを持つ unsigned char data[4]; // 葉ノードの値(8/16/32ビット) char type; // ノードの種類 NODE_INT/NODE_LEAF8/NODE_LEAF16/NODE_LEAF32/NODE_EOF } TreeNode; // S-EBXA圧縮形式 // 覚書 sliceSize 4096 スライス長 // maxSlice 2 typedef struct { int honBlkTop; // 本文(0x00)の開始ブロック番号(1〜) int honBlks; // 本文のブロック数(2048単位) int idxBlkTop; // 圧縮インデックス(0x22)の開始ブロック番号(1〜) int idxBlks; // 圧縮インデックスのブロック数(2048単位) int chonBlkTop; // 圧縮本文(0x21)の開始ブロック番号(1〜) int chonBlks; // 圧縮本文のブロック数(2048単位) #if defined(USE_SEBXA_RESIDENT_INDEX) int *idxTbl; // 圧縮インデックス(malloc)0x22の内容のコピー int nSlice; // スライス数(圧縮インデックスのエントリ数) #endif } SEBXAINFO; #if defined(_SSED_SUPPORT) // LogoVista 用拡張情報 typedef struct { unsigned char filename[32]; // ファイル名 unsigned char docId; // 書籍構成要素識別子 unsigned char multi; // 複合検索項目 long start; // 開始アドレス ( 1 origin) long end; // 終了アドレス ( 1 origin) long size; // ブロック数 unsigned char data[4]; // インデックス作成情報 FILE *fp; char compress; // 圧縮型 0:非圧縮 COMP_SSED unsigned int n_chunk; // チャンク数 #if defined(USE_SSED_RESIDENT_INDEX) unsigned char *idxTbl; // 圧縮インデックス(malloc) #endif } EXT_INFO; #endif typedef struct { /////////////////////////////////////////// // 共通 /////////////////////////////////////////// char type; // 0:非圧縮 1:ebzip 2:LogoVista 3:EPWINGV4 4:EPWINGV6 off_t fileSize; // 実ファイルサイズ size_t->off_t FILE* fp; // ファイルポインタ unsigned int blkno; // 次に読むブロック番号(seekで設定;readでインクリメント) // JIS X4081のブロック番号は1origine /////////////////////////////////////////// // 圧縮形式(EPWING/ebzip)に共通の作業領域 /////////////////////////////////////////// int sliceSize; // スライス長 // ebzipの場合は圧縮レベル(0..5)による // EPWINGの場合は2048固定とする(その代わりバッファキャッシュを多くとる) // スライスバッファはMAX_SLICE_BUF個用意し、交互に読み込む long curBlk[MAX_EPW_BUF]; // 現在読み込み中のブロック long startBlk[MAX_EPW_BUF]; // 現在読み込み中のブロックの開始ブロック番号(SSED用) unsigned char *pSlice[MAX_EPW_BUF]; // 展開後のスライスのバッファ int ixbuf; // 現在の交代バッファ int maxSlice; // スライスバッファ個数 // ebzip MAX_SLICE_BUF // EPWING MAX_EPW_BUF // S-EBXA MAX_SEBXA_BUF // LogoVista MAX_SSED_BUF /////////////////////////////////////////// // ebzip /////////////////////////////////////////// char zipMode; // 1:ebzipのzipmode // 圧縮モード。 // 元の (非圧縮時の) ファイルの大きさが 4294967295 バイト (= 4Gバイト) 以内のときは 1 (2 進数で 0001)、 // それより大きいときは 2 (2 進数で 0002) をセット。 char zipLevel; // 圧縮レベル(0..5) // 圧縮レベル スライスの大きさ // 0 2048 バイト // 1 4096 バイト // 2 8192 バイト // 3 16384 バイト // 4 32768 バイト // 5 65536 バイト char idxSize; // インデックスの大きさ(2/3/4) // 元のファイルの大きさ インデックスの大きさ // 0 〜 65535 バイト 2 バイト // 65535 〜 16777215 バイト 3 バイト // 16777216 〜 4294967295 バイト 4 バイト // 4294967296 〜 1099511627775 バイト 5 バイト off_t orgSize; // 非圧縮時のファイルサイズ size_t->off_t off_t dataOffs; // データ部の開始オフセット unsigned long CheckSum; // Adler-32 #if defined(USE_EBZIP_RESIDENT_INDEX) unsigned char *idxTbl; // 圧縮インデックス(malloc) #endif /////////////////////////////////////////// // EPWING圧縮形式 /////////////////////////////////////////// CompHdr epwHdr; // 圧縮ヘッダ TreeNode *node; // ハフマン木 int maxNode; // ルートを含めたノード数 int nNode; // ノー度数(最初は頻度表個数;ハフマン木構築後は=maxNode) int bitCount; // ビット入力カウンタ // unsigned char bitbuf; // ビット入出力バッファ int bInitiate; // 初期化 unsigned char* epwbuf; unsigned char* epwbufptr; /////////////////////////////////////////// // S-EBXA圧縮形式 /////////////////////////////////////////// SEBXAINFO sinfo; #if defined(_SSED_SUPPORT) /////////////////////////////////////////// // LogoVista / OLD EPWING /////////////////////////////////////////// short n_element; // 書籍構成要素数 EXT_INFO *extinfo; // 書籍構成要素配列 unsigned char *ssed_bookinfo; // 偽の書籍管理情報ブロック unsigned char *ssed_buff; int ssed_bufflen; #endif } ZIO_Info; class CZio { ZIO_Info m_info; TCHAR m_pszFileName[_MAX_PATH+1]; // void ( *m_callback )(LPVOID pParam,int current, int total ); LPVOID m_pParam; private: // EPWING BOOL GetBit(); TreeNode* EP_readFreqTable();// 頻度表を読込 void EP_sortTable(); // 頻度表をソート(選択ソート) void EP_makeTree(); // ハフマン木の作成 int EP_decode( /*FILE *fin,*/ unsigned char *pDst, int oMax ); // ハフマン圧縮を伸長する size_t page2Physical(int blk); // S-EBXA BOOL check_SEBXA(SEBXAINFO* sinfo); int SEBXA_decode( int srclen, // 伸長前の長さ unsigned char *outbuf, // 出力バッファ int dstlen ); // 出力バッファの長さ #if defined(_SSED_SUPPORT) int SSED_open(FILE *fp); int SSED_decode( int blk, // ブロック番号 >=1 EXT_INFO *pInfo, unsigned char *outbuf, // 出力バッファ int dstlen ); // 出力バッファの長さ #endif public: CZio(); virtual ~CZio(); int zOpen(LPCTSTR filename,int ver); void zClose(); int zSeekBlk(unsigned int blk); // blk番号は1origin int zReadBlk( unsigned char *buf); // 2048ブロック読む int zCheckCRC(); ZIO_Info*zGetInfo(); void SetCallback( void ( *callback )(LPVOID pParam,int current, int total ),LPVOID pData ); off_t GetExpandSize(); // size_t->off_t }; #endif // !defined(AFX_ZIO_H__D5B7C386_75AC_4193_AA99_B326CE9287D3__INCLUDED_)