#include "dkcLZSS.h"#include "dkcStdio.h"dkcLZSS.cのインクルード依存関係図

マクロ定義 | |
| #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) |
dkcLZSS.c で定義されています。
|
|
木の末端
参照元 DeleteNode(), InitTree(), と InsertNode(). |
|
||||||||||||||||||||
|
LZSSで圧縮されたデータを解凍します。.
-------------------------------------------------------------- ヘッダチェック -------------------------------------------------------------- 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; 参照先 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 }
|
|
||||||||||||
|
節を木から削除します。
参照先 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, と dkcAllocate().
00496 {
00497 DKC_LZSS *p = dkcAllocate(sizeof(DKC_LZSS));
00498 return p;
00499 }
|
|
|
参照先 DKC_LZSS, dkcFree(), edk_FAILED, と NULL.
00501 {
00502 if(NULL==p || NULL==*p) return edk_FAILED;
00503 return dkcFree(p);
00504 }
|
|
||||||||||||||||||||||||||||||||
|
参照先 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 }
|
|
||||||||||||||||||||||||||||||||||||
|
参照先 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 }
|
|
||||||||||||||||||||||||||||||||
|
データをLZSSで圧縮します。
圧縮したサイズ?を取得 参照先 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 }
|
|
|
圧縮・解凍用の木のデータを初期化します。
参照先 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 }
|
|
||||||||||||
|
節を木に挿入します。
参照先 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 }
|
1.3.6