49 #define TNB_SLD_HEAD "SLD"
50 #define TNB_SLD_NON TNB_SLD_HEAD "0"
51 #define TNB_SLD_LV1 TNB_SLD_HEAD "1"
70 MAX_HASH_VAL= (3 * DIC_SIZE + (DIC_SIZE / 512 + 1) * UCHAR_MAX)
72 BYTE text[DIC_SIZE * 2 + MAXMATCH];
73 int level[DIC_SIZE + UCHAR_MAX + 1];
74 int childcount[DIC_SIZE + UCHAR_MAX + 1];
75 int position[DIC_SIZE + UCHAR_MAX + 1];
76 int parent[DIC_SIZE * 2];
77 int prev[DIC_SIZE * 2];
78 int next[MAX_HASH_VAL + 1];
93 int m_Hash(
int p,
int c)
95 return ((p) + ((c) << (DIC_BIT - 9)) + DIC_SIZE * 2);
99 void insert_node(
void)
105 if ( m_iMatchLen >= 4 )
108 r = (m_iMatchPos + 1) | DIC_SIZE;
109 while ( (q = B.parent[r]) == NIL )
113 while ( B.level[q] >= m_iMatchLen )
119 while ( t < DIC_SIZE )
121 B.position[t] = m_iPos;
127 q = B.text[m_iPos] + DIC_SIZE;
128 c = B.text[m_iPos + 1];
129 r = searchchild(q, c);
132 makechild(q, c, m_iPos);
148 m_iMatchPos = B.position[r];
150 if ( m_iMatchPos >= m_iPos )
152 m_iMatchPos -= DIC_SIZE;
154 t1 = &B.text[m_iPos + m_iMatchLen];
155 t2 = &B.text[m_iMatchPos + m_iMatchLen];
156 while ( m_iMatchLen < j )
167 if ( m_iMatchLen == MAXMATCH )
171 B.position[r] = m_iPos;
173 r = searchchild(q, *t1);
176 makechild(q, *t1, m_iPos);
181 t = B.prev[r]; B.prev[m_iPos] = t; B.next[t] = m_iPos;
182 t = B.next[r]; B.next[m_iPos] = t; B.prev[t] = m_iPos;
183 B.parent[m_iPos] = q; B.parent[r] = NIL;
188 void delete_node(
void)
192 if ( B.parent[m_iPos] == NIL )
200 r = B.parent[m_iPos];
201 B.parent[m_iPos] = NIL;
202 if ( r >= DIC_SIZE || --B.childcount[r] > 1 )
211 s = searchchild(r, B.text[t + B.level[r]]);
212 t = B.prev[s]; u = B.next[s];
213 B.next[t] = u; B.prev[u] = t;
214 t = B.prev[r]; B.next[t] = s; B.prev[s] = t;
215 t = B.next[r]; B.prev[t] = s; B.next[s] = t;
216 B.parent[s] = B.parent[r];
218 B.next[r] = m_iAvail;
223 int searchchild(
int q, BYTE c)
227 r = B.next[m_Hash(q, c)];
229 while ( B.parent[r] != q )
237 void makechild(
int q, BYTE c,
int r)
242 t = B.next[h]; B.next[h] = r; B.next[r] = t;
243 B.prev[t] = r; B.prev[r] = h;
253 sNew = m_iAvail; m_iAvail = B.next[sNew]; B.childcount[sNew] = 0;
254 t = B.prev[old]; B.prev[sNew] = t; B.next[t] = sNew;
255 t = B.next[old]; B.next[sNew] = t; B.prev[t] = sNew;
256 B.parent[sNew] = B.parent[old];
257 B.level[sNew] = m_iMatchLen;
258 B.position[sNew] = m_iPos;
259 makechild(sNew, B.text[m_iMatchPos + m_iMatchLen], old);
260 makechild(sNew, B.text[m_iPos + m_iMatchLen], m_iPos);
264 bool m_Copy(
size_t iLen)
270 int m_Read(LPVOID lpBuf,
int iLen)
272 if ( iLen + m_iSrcPos > m_iSrcSize )
274 iLen = m_iSrcSize - m_iSrcPos;
276 BYTE* B =
static_cast<BYTE*
>(lpBuf);
279 *B++ = m_pSrcDat->
At(m_iSrcPos++);
285 bool m_Write(LPCVOID lpBuf,
size_t iLen)
287 return m_pDstDat->
AddElements(iLen,
static_cast<const BYTE*
>(lpBuf)) == iLen;
294 bool m_EncodePlain(
void)
300 r &= m_Write(&m_iSrcSize, 4);
301 r &= m_Write(&m_iSrcSize, 4);
302 r &= m_Copy(m_iSrcSize);
325 if ( m_iSrcSize == 0 || boIsPlain )
328 return m_EncodePlain();
334 m_iPos = DIC_SIZE + MAXMATCH;
336 for (
int i = DIC_SIZE; i <= DIC_SIZE + UCHAR_MAX; i++ )
340 for (
int i = DIC_SIZE; i < DIC_SIZE * 2; i++ )
344 for (
int i = 1; i < DIC_SIZE - 1; i++ )
348 B.next[DIC_SIZE - 1] = NIL;
349 for (
int i = DIC_SIZE * 2; i <= TBuf::MAX_HASH_VAL; i++ )
361 r &= m_Write(&m_iSrcSize, 4);
362 r &= m_Write(&m_iSrcSize, 4);
364 int remainder = m_Read(&B.text[m_iPos], DIC_SIZE);
366 while ( remainder > 0 )
368 int lastmatchlen = m_iMatchLen;
369 int lastmatchpos = m_iMatchPos;
371 if ( ++m_iPos == DIC_SIZE * 2 )
373 MemCopy(&B.text[0], &B.text[DIC_SIZE], DIC_SIZE + MAXMATCH);
374 m_Read(&B.text[DIC_SIZE + MAXMATCH], DIC_SIZE);
375 remainder += DIC_SIZE;
380 if ( m_iMatchLen > remainder )
382 m_iMatchLen = remainder;
384 if ( m_iMatchLen > lastmatchlen || lastmatchlen < THRESHOLD )
386 code[codeptr++] = B.text[m_iPos - 1];
391 code[codeptr++] =
static_cast<BYTE
>(m_iPos - 1 - lastmatchpos);
392 code[codeptr++] =
static_cast<BYTE
>((((m_iPos - 1 - lastmatchpos) >> 4) & 0xf0) | (lastmatchlen - THRESHOLD));
393 remainder = remainder - lastmatchlen + 1;
394 while ( --lastmatchlen > 0 )
396 if ( ++m_iPos == DIC_SIZE * 2 )
398 MemCopy(&B.text[0], &B.text[DIC_SIZE], DIC_SIZE + MAXMATCH);
399 m_Read(&B.text[DIC_SIZE + MAXMATCH], DIC_SIZE);
400 remainder += DIC_SIZE;
406 if ( m_iMatchLen > remainder )
408 m_iMatchLen = remainder;
411 if ( (mask <<= 1) == 0 )
413 if ( comp_size + codeptr + 8 > m_iSrcSize )
416 return m_EncodePlain();
418 r &= m_Write(&code[0], codeptr);
419 comp_size += codeptr;
426 r &= m_Write(&code[0], codeptr);
427 comp_size += codeptr;
429 if ( comp_size + 8 > m_iSrcSize )
432 return m_EncodePlain();
434 ASSERTLIB(
ToInt(m_pDstDat->
GetSize()) == comp_size + 12 );
469 if ( lLen1 != lLen2 )
486 for (
int i = 0; i < DIC_SIZE - MAXMATCH; i++ )
501 if ( m_Read(&flags, 1) != 1 )
508 if ( (flags & 1) != 0 )
511 if ( m_Read(&fd, 1) != 1 )
516 if ( posi == DIC_SIZE || count + posi >= fl )
518 r &= m_Write(B.text, posi);
526 if ( m_Read(&fd, 2) != 2 )
532 d1 |= ((d2 & 0xf0) << 4);
533 d2 = (d2 & 0x0f) + 2;
535 for (
int k = 0; k <= d2; k++ )
537 B.text[posi++] = B.text[(d1 + k) & (DIC_SIZE - 1)];
538 if ( posi == DIC_SIZE || count + posi >= fl )
540 r &= m_Write(B.text, posi);
552 }
while ( --g != 0 );
560 r &= m_Write(B.text, posi);
577 if ( m_ptBuf != NULL )
596 return m_Encode(_out, in, boIsPlain);
611 if ( !
Encode(vb, in, boIsPlain) )
628 return m_Decode(_out, in);
679 if ( lLen1 != lLen2 )
687 friend class CSlideCompressorTest;
#define loop(VAR, CNT)
loop構文.
#define TNB_SLD_LV1
圧縮1データヘッダ
#define TNB_SLD_NON
非圧縮データヘッダ
#define TNB_SLD_HEAD
ヘッダベース
bool Decode(ICollectionT< BYTE > &_out, const IConstCollectionT< BYTE > &in)
[処理] 展開
CByteVector Encode(const IConstCollectionT< BYTE > &in, bool boIsPlain=false)
[処理] 圧縮
CSlideCompressor(void)
コンストラクタ
CByteVector Decode(const IConstCollectionT< BYTE > &in)
[処理] 展開
~CSlideCompressor(void)
デストラクタ
int GetSizeAfterDecoding(const IConstCollectionT< BYTE > &in)
[取得] 展開サイズ
bool Encode(ICollectionT< BYTE > &_out, const IConstCollectionT< BYTE > &in, bool boIsPlain=false)
[処理] 圧縮
void SetIncrementSize(size_t size)
[設定] 余白サイズ
void Invalid(void)
[操作] 無効状態にする
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
virtual bool RemoveAll(void)
[削除] 全要素削除 .
virtual size_t AddElements(size_t size, const TYP *P=NULL)
[追加] 複数要素追加.
virtual size_t Append(const IConstCollectionT< TYP > &c)
[追加] 追加.
virtual const TYP & At(INDEX index) const =0
[取得] 要素の参照取得.
virtual size_t GetSize(void) const =0
[取得] 要素数取得.