メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcLZSS.c

#include "dkcLZSS.h"
#include "dkcStdio.h"

dkcLZSS.cのインクルード依存関係図

Include dependency graph

ソースコードを見る。

マクロ定義

#define NIL   LZSS_RING_LENGTH
 木の末端


関数

void InitTree (DKC_LZSS *pWork)
 圧縮・解凍用の木のデータを初期化します。

void InsertNode (DKC_LZSS *pWork, long r)
 節を木に挿入します。

void DeleteNode (DKC_LZSS *pWork, long p)
 節を木から削除します。

BOOL Decode (DKC_LZSS *pWork, DKC_LZSS_HEADER *ph, const void *pSrc, void *pDst)
 LZSSで圧縮されたデータを解凍します。.

BOOL Encode (DKC_LZSS *pWork, const void *pSrc, unsigned long SrcSize, void *pDst, size_t DstSize, unsigned long *pDstSize, size_t CloseProcessSize)
 データをLZSSで圧縮します。

DKC_LZSS *WINAPI dkcAllocLZSS ()
int WINAPI dkcFreeLZSS (DKC_LZSS **p)
int WINAPI dkcLZSSDecode (DKC_LZSS *ptr, DKC_LZSS_HEADER *ph, BYTE *dest, size_t dsize, const BYTE *src, size_t ssize, ULONG sig)
int WINAPI dkcLZSSEncode (DKC_LZSS *ptr, DKC_LZSS_HEADER *ph, BYTE *dest, size_t dsize, const BYTE *src, size_t ssize, size_t CloseProcessSize, ULONG sig)


説明

d金魚
から:
2004/04/20

dkcLZSS.c で定義されています。


マクロ定義

#define NIL   LZSS_RING_LENGTH
 

木の末端

dkcLZSS.c16 行で定義されています。

参照元 DeleteNode(), InitTree(), と InsertNode().


関数

BOOL Decode DKC_LZSS pWork,
DKC_LZSS_HEADER ph,
const void *  pSrc,
void *  pDst
[static]
 

LZSSで圧縮されたデータを解凍します。.

引数:
pSrc [in] 圧縮されたデータ
pDst [out] 展開後のデータ
戻り値:
TRUE 成功
FALSE 失敗

-------------------------------------------------------------- ヘッダチェック -------------------------------------------------------------- if ( ((LZSS_HEADER*)pSrc)->Guid[0] != 'L' ) return FALSE; if ( ((LZSS_HEADER*)pSrc)->Guid[1] != 'Z' ) return FALSE; if ( ((LZSS_HEADER*)pSrc)->Guid[2] != 'S' ) return FALSE; if ( ((LZSS_HEADER*)pSrc)->Guid[3] != 'S' ) return FALSE;

dkcLZSS.c224 行で定義されています。

参照先 BOOL, DKC_LZSS, DKC_LZSS_HEADER, LZSS_LONGEST_MATCH, LZSS_RING_LENGTH, dkc_LZSS_Header::mOriginSize, dkc_LZSS::Text, と TRUE.

参照元 dkcLZSSDecode().

00226 {
00227     long r = LZSS_RING_LENGTH - LZSS_LONGEST_MATCH;
00228     unsigned long Flags = 0;
00229     unsigned char c;
00230 
00231     unsigned char *pDstData = (unsigned char*)pDst;
00232     //unsigned char *pSrcData = (unsigned char*)pSrc + sizeof(LZSS_HEADER);
00233     unsigned char *pSrcData = (unsigned char*)pSrc;
00234     //--------------------------------------------------------------
00235     // 展開後サイズ取得
00236     //--------------------------------------------------------------
00237     //unsigned long DstSize = ((LZSS_HEADER*)pSrc)->OriginalSize;
00238     unsigned long DstSize = ph->mOriginSize;
00239 
00240     long k = 0;
00241     //MemoryClear( pWork->Text, sizeof(pWork->Text) );
00242     memset(pWork->Text,0,sizeof(pWork->Text) );
00252     //--------------------------------------------------------------
00253     // デコード処理
00254     //--------------------------------------------------------------
00255     while ( TRUE )
00256     {
00257         Flags >>= 1;
00258         if ( (Flags & 256) == 0 )
00259         {
00260             c = *( pSrcData++ );
00261             Flags = c | 0xff00;
00262         }
00263 
00264         if ( Flags & 1 )
00265         {
00266             c = *(pSrcData++);
00267             *(pDstData++) = c;
00268             if ( --DstSize == 0 ) return TRUE;
00269 
00270             pWork->Text[r++] = c;
00271             r &= (LZSS_RING_LENGTH - 1);
00272         }
00273         else
00274         {
00275             long i = *(pSrcData++);
00276             long j = *(pSrcData++);
00277             i |= ((j & 0xF0) << 4);
00278             j = (j & 0x0F) + 2;
00279 
00280             //for ( long k = 0; k <= j; k++ )
00281             for ( k = 0; k <= j; k++ )
00282             {
00283                 c = pWork->Text[(i + k) & (LZSS_RING_LENGTH - 1)];
00284                 *(pDstData++) = c;
00285                 if ( --DstSize == 0 ) return TRUE;
00286 
00287                 pWork->Text[r++] = c;
00288                 r &= (LZSS_RING_LENGTH - 1);
00289             }
00290         }
00291     }
00292 
00293     //return FALSE;
00294 }

void DeleteNode DKC_LZSS pWork,
long  p
[static]
 

節を木から削除します。

引数:
p [in] 削除するデータ

dkcLZSS.c166 行で定義されています。

参照先 dkc_LZSS::Dad, DKC_LZSS, dkc_LZSS::LSon, NIL, と dkc_LZSS::RSon.

参照元 Encode().

00167 {
00168     long q = -1;
00169 
00170     if ( pWork->Dad[p]  == NIL ) return;
00171 
00172     if ( pWork->RSon[p] == NIL )
00173     {
00174         q = pWork->LSon[p];
00175     }
00176     else if( pWork->LSon[p] == NIL )
00177     {
00178         q = pWork->RSon[p];
00179     }
00180     else
00181     {
00182         q = pWork->LSon[p];
00183 
00184         if ( pWork->RSon[q] != NIL )
00185         {
00186             do { q = pWork->RSon[q]; } while ( pWork->RSon[q] != NIL );
00187 
00188             pWork->RSon[pWork->Dad[q]]  = pWork->LSon[q];
00189             pWork->Dad[pWork->LSon[q]]  = pWork->Dad[q];
00190             pWork->LSon[q]              = pWork->LSon[p];
00191             pWork->Dad[pWork->LSon[p]]  = q;
00192         }
00193 
00194         pWork->RSon[q] = pWork->RSon[p];
00195         pWork->Dad[pWork->RSon[p]]  = q;
00196     }
00197 
00198     pWork->Dad[q] = pWork->Dad[p];
00199     if ( pWork->RSon[pWork->Dad[p]] == p )
00200     {
00201         pWork->RSon[pWork->Dad[p]] = q;
00202     }
00203     else
00204     {
00205         pWork->LSon[pWork->Dad[p]] = q;
00206     }
00207 
00208     pWork->Dad[p] = NIL;
00209 }

DKC_LZSS* WINAPI dkcAllocLZSS  ) 
 

dkcLZSS.c495 行で定義されています。

参照先 DKC_LZSS, と dkcAllocate().

00496 {
00497     DKC_LZSS *p = dkcAllocate(sizeof(DKC_LZSS));
00498     return p;
00499 }

int WINAPI dkcFreeLZSS DKC_LZSS **  p  ) 
 

dkcLZSS.c501 行で定義されています。

参照先 DKC_LZSS, dkcFree(), edk_FAILED, と NULL.

00501                                     {
00502     if(NULL==p || NULL==*p) return edk_FAILED;
00503     return dkcFree(p);
00504 }

int WINAPI dkcLZSSDecode DKC_LZSS ptr,
DKC_LZSS_HEADER ph,
BYTE dest,
size_t  dsize,
const BYTE src,
size_t  ssize,
ULONG  sig
 

引数:
ptr[in][out] dkcAllocLZSS()で取得したポインタ
ph[out] DKC_LZSS_HEADERへのポインタ
dest[out] デコードされたデータの書き出しバッファへのポインタ
dsize[in] destのサイズ
src[in] バッファへのポインタ
ssize[in] srcのサイズ
sig[in] dkcLZSSEncode()の時、指定したシグネチャID
戻り値:
edk_Resultのどれかが返る。
覚え書き:
DKC_LZSS_HEADERのメンバのmOriginSizeよりdsizeが小さいとこの関数は失敗します。

dkcLZSS.c507 行で定義されています。

参照先 BYTE, Decode(), DKC_LZSS, DKC_LZSS_HEADER, edk_ArgumentException, edk_BufferOverFlow, edk_FAILED, edk_SUCCEEDED, FALSE, dkc_LZSS_Header::mOriginSize, dkc_LZSS_Header::mSignature, と NULL.

00509 {
00510     if(NULL==ptr || NULL==ph)
00511         return edk_ArgumentException;
00512 
00513     if(ph->mOriginSize > dsize){
00514         return edk_BufferOverFlow;
00515         }
00516     //if(dkcLZSSIsLZSS(ph)==FALSE){
00517     if(ph->mSignature != sig){
00518         return edk_FAILED;
00519         }
00520 
00521     if(FALSE==Decode(ptr,ph,src,dest)){
00522         return edk_FAILED;
00523         }
00524 
00525     return edk_SUCCEEDED;
00526 
00527 }

int WINAPI dkcLZSSEncode DKC_LZSS ptr,
DKC_LZSS_HEADER ph,
BYTE dest,
size_t  dsize,
const BYTE src,
size_t  ssize,
size_t  CloseProcessSize,
ULONG  sig
 

引数:
ptr[in][out] dkcAllocLZSS()で取得したポインタ
ph[out] DKC_LZSS_HEADERへのポインタ
dest[out] LZSSで圧縮されたデータの書き出しバッファへのポインタ
dsize[in] destのサイズ
src[in] バッファへのポインタ
ssize[in] srcのサイズ
CloseProcessSize[in] 処理を打ち切りにするサイズ dsizeより小さくするのがセオリー
sig[in] LZSSだと証明するシグネチャ
戻り値:
edk_Resultのどれかが返る。圧縮する価値の無い場合はedk_NoValueToProcessが返る。

dkcLZSS.c529 行で定義されています。

参照先 BYTE, DKC_LZSS, DKC_LZSS_HEADER, dkcmNOT_ASSERT, DKUTIL_FAILED, edk_ArgumentException, Encode(), dkc_LZSS_Header::mCompressedSize, dkc_LZSS_Header::mOriginSize, dkc_LZSS_Header::mSignature, と NULL.

00532 {
00533     unsigned long comped;
00534     int result;
00535 
00536     if(NULL==ptr || NULL==ph)
00537         return edk_ArgumentException;
00538     
00539     dkcmNOT_ASSERT(NULL==dest || 0==dsize);
00540 
00541 
00542     result = Encode(ptr,src,ssize,dest,dsize,&comped,CloseProcessSize);
00543     if(DKUTIL_FAILED(result))
00544     {
00545         return result;
00546     }
00547     ph->mOriginSize = (size_t)ssize;
00548     ph->mCompressedSize = comped;
00549     ph->mSignature =  sig;
00550 
00551     return result;
00552 
00553 }

BOOL Encode DKC_LZSS pWork,
const void *  pSrc,
unsigned long  SrcSize,
void *  pDst,
size_t  DstSize,
unsigned long *  pDstSize,
size_t  CloseProcessSize
[static]
 

データをLZSSで圧縮します。

引数:
pSrc [in] 圧縮するデータ
SrcSize [in] 圧縮元データ(pSrc)のサイズ
pDst [out] 圧縮後のデータ格納先
DstSize[in] pDstバッファのサイズ
pDstSize [out] 圧縮後のデータサイズ
CloseProcessSize[in] 処理を打ち切りするサイズ SrcSizeより小さくするのがセオリー
戻り値:
edk_Resultのどれか。詳しくは実装を見よう!(オイ

圧縮したサイズ?を取得

dkcLZSS.c309 行で定義されています。

参照先 BOOL, DeleteNode(), DKC_LZSS, edk_BufferOverFlow, edk_NoValueToProcess, edk_SUCCEEDED, FALSE, InitTree(), InsertNode(), LZSS_LONGEST_MATCH, LZSS_RING_LENGTH, dkc_LZSS::MatchLen, dkc_LZSS::MatchPos, と dkc_LZSS::Text.

参照元 dkcLZSSEncode().

00314 {
00315     unsigned char   Code[17]        = { 0 };
00316     unsigned char   Mask            = 1;
00317     long            i               = 0;
00318     long            Len             = 0;
00319     long            CodePtr         = 1;
00320     long            LastMatchLen    = 0;
00321     long            s               = 0;
00322     long            r               = LZSS_RING_LENGTH - LZSS_LONGEST_MATCH;
00323     
00324     //バッファ漏れとかのチェック変数だと思う。
00325     //圧縮率100%以上じゃないと認めない。
00326     //unsigned long SrcCheckSize    = SrcSize;//SrcSize * 2; 
00327     unsigned long SrcCheckSize = CloseProcessSize;
00328 
00329     //unsigned char *pDstData = (unsigned char *)pDst + sizeof(LZSS_HEADER);
00330     unsigned char *pDstData = (unsigned char *)pDst;
00331     unsigned char *pSrcData = (unsigned char *)pSrc;
00332 
00333 
00334 
00335     unsigned char c;
00336     //圧縮する価値があるかどうかカウント
00337     ULONG CompressByte = 0;
00338 
00339     //--------------------------------------------------------------
00340     // LZSSヘッダの作成
00341     //--------------------------------------------------------------
00342     /*
00343     ((LZSS_HEADER*)pDst)->Guid[0] = 'L';
00344     ((LZSS_HEADER*)pDst)->Guid[1] = 'Z';
00345     ((LZSS_HEADER*)pDst)->Guid[2] = 'S';
00346     ((LZSS_HEADER*)pDst)->Guid[3] = 'S';
00347     ((LZSS_HEADER*)pDst)->OriginalSize = SrcSize;
00348     */
00349     //pHeader->mOriginSize = SrcSize;
00350     //--------------------------------------------------------------
00351     // 転送先サイズ
00352     //--------------------------------------------------------------
00353     //(*pDstSize) = sizeof(LZSS_HEADER);
00354     (*pDstSize) = 0;
00355     //--------------------------------------------------------------
00356     // 木を初期化
00357     //--------------------------------------------------------------
00358     InitTree(pWork );
00359 
00360     //--------------------------------------------------------------
00361     // バッファを初期化
00362     //--------------------------------------------------------------
00363     for ( i = s; i < r; i++ ) pWork->Text[i] = 0;
00364 
00365     for ( Len = 0; Len < LZSS_LONGEST_MATCH ; Len++ )
00366     {
00367         unsigned char c = *(pSrcData++);
00368         if ( --SrcSize <= 0 ) break;
00369         pWork->Text[r + Len] = c;
00370     }
00371 
00372     if ( Len == 0 ) return FALSE;
00373 
00374     for ( i = 1; i <= LZSS_LONGEST_MATCH; i++ )
00375     {
00376         InsertNode(pWork, r - i );
00377     }
00378 
00379     InsertNode(pWork, r );
00380 
00381     //--------------------------------------------------------------
00382     // エンコード処理
00383     //--------------------------------------------------------------
00384     do
00385     {
00386         if ( pWork->MatchLen > Len )
00387         {
00388             pWork->MatchLen = Len;
00389         }
00390 
00391         if ( pWork->MatchLen < 3 )
00392         {
00393             pWork->MatchLen = 1;
00394             Code[0] |= Mask;
00395             Code[CodePtr++] = pWork->Text[r];
00396         }
00397         else
00398         {
00399             Code[CodePtr++] = (unsigned char)pWork->MatchPos;
00400             Code[CodePtr++] = (unsigned char)(((pWork->MatchPos >> 4) & 0xF0) | (pWork->MatchLen - 3) );
00401         }
00402 
00403         if ( (Mask <<= 1) == 0 )
00404         {
00405             (*pDstSize) += CodePtr;
00406 
00407             if ( SrcCheckSize <= (*pDstSize) )
00408             {
00409                 //goto EXIT;
00410                 //圧縮する価値は無いよ!
00411                 return edk_NoValueToProcess;
00412             }
00413 
00414             CompressByte += CodePtr;
00415             if(CompressByte >= DstSize)
00416             {//バッファが漏れる也!
00417                 return edk_BufferOverFlow;
00418             }
00419                 
00420             for ( i = 0; i < CodePtr; i++ )
00421             {//多分、コピーする処理。
00422                 *(pDstData++) = Code[i];
00423 
00424 
00425             }
00426             Code[0] = 0;
00427             CodePtr = Mask = 1;
00428         }
00429 
00430         LastMatchLen = pWork->MatchLen;
00431 
00432         for ( i = 0; i < LastMatchLen; i++ )
00433         {
00434             if ( SrcSize == 0 ) break;
00435             SrcSize--;
00436 
00437             //unsigned char c = *(pSrcData++);
00438             c = *(pSrcData++);
00439             //DeleteNode( s );
00440             DeleteNode(pWork,s);
00441             pWork->Text[s] = c;
00442             if ( s < LZSS_LONGEST_MATCH - 1 )
00443             {
00444                 pWork->Text[s + LZSS_RING_LENGTH] = c;
00445             }
00446             s = (s + 1) & (LZSS_RING_LENGTH - 1);
00447             r = (r + 1) & (LZSS_RING_LENGTH - 1);
00448             InsertNode(pWork, r );
00449         }
00450 
00451         while ( i++ < LastMatchLen )
00452         {
00453             DeleteNode(pWork, s );
00454             s = (s + 1) & (LZSS_RING_LENGTH - 1);
00455             r = (r + 1) & (LZSS_RING_LENGTH - 1);
00456             if ( --Len ) InsertNode(pWork, r );
00457         }
00458     }
00459     while ( Len > 0 );
00460 
00461     //--------------------------------------------------------------
00462     // 後処理
00463     //--------------------------------------------------------------
00464     if ( CodePtr > 1 )
00465     {
00466         (*pDstSize) += CodePtr;
00467         // 展開先バッファ溢れ
00468         if ( SrcCheckSize > (*pDstSize) )
00469         {
00470             //バッファが漏れているツーに
00471             CompressByte += CodePtr;
00472             if(CompressByte >= DstSize){
00473                 return edk_BufferOverFlow;
00474             }
00475             for ( i = 0; i < CodePtr; i++ )
00476             {
00477                 *(pDstData++) = Code[i];
00478 
00479             }
00480         }
00481     }
00482 
00483 //EXIT:
00485     //*CompressedByte = CompressByte;
00486     return edk_SUCCEEDED;
00487 }

void InitTree DKC_LZSS pWork  )  [static]
 

圧縮・解凍用の木のデータを初期化します。

dkcLZSS.c60 行で定義されています。

参照先 dkc_LZSS::Dad, DKC_LZSS, LZSS_RING_LENGTH, NIL, と dkc_LZSS::RSon.

参照元 Encode().

00061 {
00062     long i;
00063     for (i = LZSS_RING_LENGTH+1; i <= LZSS_RING_LENGTH+256; i++ )
00064     {
00065         pWork->RSon[i] = NIL;
00066     }
00067 
00068     for (i = 0; i < LZSS_RING_LENGTH; i++ )
00069     {
00070         pWork->Dad[i] = NIL;
00071     }
00072 }

void InsertNode DKC_LZSS pWork,
long  r
[static]
 

節を木に挿入します。

引数:
r [in] 挿入するデータ

dkcLZSS.c81 行で定義されています。

参照先 dkc_LZSS::Dad, DKC_LZSS, dkc_LZSS::LSon, LZSS_LONGEST_MATCH, LZSS_RING_LENGTH, dkc_LZSS::MatchLen, dkc_LZSS::MatchPos, NIL, dkc_LZSS::RSon, dkc_LZSS::Text, と TRUE.

参照元 Encode().

00082 {
00083     long cmp = 1;
00084     unsigned char *pKey = &pWork->Text[r];
00085     long p = LZSS_RING_LENGTH + 1 + pKey[0];
00086     long i = 0;
00087 
00088     pWork->RSon[r] = pWork->LSon[r] = NIL;
00089     pWork->MatchLen = 0;
00090 
00091     while( TRUE )
00092     {
00093         if ( cmp >= 0 )
00094         {
00095             if ( pWork->RSon[p] != NIL )
00096             {
00097                 p = pWork->RSon[p];
00098             }
00099             else
00100             {
00101                 pWork->RSon[p] = r;
00102                 pWork->Dad[r] = p;
00103                 return;
00104             }
00105         }
00106         else
00107         {
00108             if ( pWork->LSon[p] != NIL )
00109             {
00110                 p = pWork->LSon[p];
00111             }
00112             else
00113             {
00114                 pWork->LSon[p] = r;
00115                 pWork->Dad[r] = p;
00116                 return;
00117             }
00118         }
00119 
00120 
00121         for ( i = 1; i < LZSS_LONGEST_MATCH; i++ )
00122         {
00123             cmp = pKey[i] - pWork->Text[p + i];
00124             if ( cmp != 0 )
00125             {
00126                 break;
00127             }
00128         }
00129 
00130         if ( i > pWork->MatchLen )
00131         {
00132             pWork->MatchPos = p;
00133             pWork->MatchLen = i;
00134             if ( pWork->MatchLen >= LZSS_LONGEST_MATCH )
00135             {
00136                 break;
00137             }
00138         }
00139     }
00140 
00141     pWork->Dad[r]           = pWork->Dad[p];
00142     pWork->LSon[r]          = pWork->LSon[p];
00143     pWork->RSon[r]          = pWork->RSon[p];
00144     pWork->Dad[pWork->LSon[p]]  = r;
00145     pWork->Dad[pWork->RSon[p]]  = r;
00146 
00147     if ( pWork->RSon[pWork->Dad[p]] == p )
00148     {
00149         pWork->RSon[pWork->Dad[p]] = r;
00150     }
00151     else
00152     {
00153         pWork->LSon[pWork->Dad[p]] = r;
00154     }
00155 
00156     pWork->Dad[p] = NIL;
00157 }


dkutil_cに対してSun Jul 18 22:45:47 2004に生成されました。 doxygen 1.3.6