#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 } |