📄 nrv2b.c
字号:
--s->node_count;}/***********************************************************************//************************************************************************/staticvoid swd_accept(struct ucl_swd *s, unsigned int n){ assert(n <= s->look); if (n > 0) do { unsigned int key; swd_remove_node(s,s->rp); /* add bp into HEAD3 */ key = HEAD3(s->b,s->bp); s->succ3[s->bp] = s_head3(s,key); s->head3[key] = (unsigned int)(s->bp); s->best3[s->bp] = (unsigned int)(s->f + 1); s->llen3[key]++; assert(s->llen3[key] <= s->n); /* add bp into HEAD2 */ key = HEAD2(s->b,s->bp); s->head2[key] = (unsigned int)(s->bp); swd_getbyte(s); } while (--n > 0);}/***********************************************************************//************************************************************************/staticvoid swd_search(struct ucl_swd *s, unsigned int node, unsigned int cnt){ const unsigned char *p1; const unsigned char *p2; const unsigned char *px; unsigned int m_len = s->m_len; const unsigned char * b = s->b; const unsigned char * bp = s->b + s->bp; const unsigned char * bx = s->b + s->bp + s->look; unsigned char scan_end1; assert(s->m_len > 0); scan_end1 = bp[m_len - 1]; for ( ; cnt-- > 0; node = s->succ3[node]) { p1 = bp; p2 = b + node; px = bx; assert(m_len < s->look); if ( p2[m_len - 1] == scan_end1 && p2[m_len] == p1[m_len] && p2[0] == p1[0] && p2[1] == p1[1]) { unsigned int i; assert(memcmp(bp,&b[node],3) == 0); p1 += 2; p2 += 2; do {} while (++p1 < px && *p1 == *++p2); i = p1 - bp; #ifdef UCL_DEBUG if (memcmp(bp,&b[node],i) != 0) printf("%5ld %5ld %02x%02x %02x%02x\n", (long)s->bp, (long) node, bp[0], bp[1], b[node], b[node+1]);#endif assert(memcmp(bp,&b[node],i) == 0); #if defined(SWD_BEST_OFF) if (i < SWD_BEST_OFF) { if (s->best_pos[i] == 0) s->best_pos[i] = node + 1; }#endif if (i > m_len) { s->m_len = m_len = i; s->m_pos = node; if (m_len == s->look) return; if (m_len >= s->nice_length) return; if (m_len > (unsigned int) s->best3[node]) return; scan_end1 = bp[m_len - 1]; } } }}static int swd_search2(struct ucl_swd *s){ unsigned int key; assert(s->look >= 2); assert(s->m_len > 0); key = s->head2[ HEAD2(s->b,s->bp) ]; if (key == NIL2) return 0;#ifdef UCL_DEBUG if (memcmp(&s->b[s->bp],&s->b[key],2) != 0) printf("%5ld %5ld %02x%02x %02x%02x\n", (long)s->bp, (long)key, s->b[s->bp], s->b[s->bp+1], s->b[key], s->b[key+1]);#endif assert(memcmp(&s->b[s->bp],&s->b[key],2) == 0);#if defined(SWD_BEST_OFF) if (s->best_pos[2] == 0) s->best_pos[2] = key + 1;#endif if (s->m_len < 2) { s->m_len = 2; s->m_pos = key; } return 1;}/***********************************************************************//************************************************************************/staticvoid swd_findbest(struct ucl_swd *s){ unsigned int key; unsigned int cnt, node; unsigned int len; assert(s->m_len > 0); /* get current head, add bp into HEAD3 */ key = HEAD3(s->b,s->bp); node = s->succ3[s->bp] = s_head3(s,key); cnt = s->llen3[key]++; assert(s->llen3[key] <= s->n + s->f); if (cnt > s->max_chain && s->max_chain > 0) cnt = s->max_chain; s->head3[key] = (unsigned int)(s->bp); s->b_char = s->b[s->bp]; len = s->m_len; if (s->m_len >= s->look) { if (s->look == 0) s->b_char = -1; s->m_off = 0; s->best3[s->bp] = (unsigned int)(s->f + 1); } else { if (swd_search2(s)) if (s->look >= 3) swd_search(s,node,cnt); if (s->m_len > len) s->m_off = swd_pos2off(s,s->m_pos); s->best3[s->bp] = (unsigned int)(s->m_len);#if defined(SWD_BEST_OFF) if (s->use_best_off) { int i; for (i = 2; i < SWD_BEST_OFF; i++) if (s->best_pos[i] > 0) s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1); else s->best_off[i] = 0; }#endif } swd_remove_node(s,s->rp); /* add bp into HEAD2 */ key = HEAD2(s->b,s->bp); s->head2[key] = (unsigned int)(s->bp);}/***********************************************************************//************************************************************************/static intinit_match ( struct ucl_compress *c, struct ucl_swd *s, const uint8_t *dict, unsigned int dict_len, uint32_t flags ){ int r; assert(!c->init); c->init = 1; s->c = c; c->last_m_len = c->last_m_off = 0; c->textsize = c->codesize = c->printcount = 0; c->lit_bytes = c->match_bytes = c->rep_bytes = 0; c->lazy = 0; r = swd_init(s,dict,dict_len); if (r != UCL_E_OK) { swd_exit(s); return r; } s->use_best_off = (flags & 1) ? 1 : 0; return UCL_E_OK;}static intfind_match ( struct ucl_compress *c, struct ucl_swd *s, unsigned int this_len, unsigned int skip ){ assert(c->init); if (skip > 0) { assert(this_len >= skip); swd_accept(s, this_len - skip); c->textsize += this_len - skip + 1; } else { assert(this_len <= 1); c->textsize += this_len - skip; } s->m_len = THRESHOLD;#ifdef SWD_BEST_OFF if (s->use_best_off) memset(s->best_pos,0,sizeof(s->best_pos));#endif swd_findbest(s); c->m_len = s->m_len; c->m_off = s->m_off; swd_getbyte(s); if (s->b_char < 0) { c->look = 0; c->m_len = 0; swd_exit(s); } else { c->look = s->look + 1; } c->bp = c->ip - c->look; #if 0 /* brute force match search */ if (c->m_len > THRESHOLD && c->m_len + 1 <= c->look) { const uint8_t *ip = c->bp; const uint8_t *m = c->bp - c->m_off; const uint8_t *in = c->in; if (ip - in > N) in = ip - N; for (;;) { while (*in != *ip) in++; if (in == ip) break; if (in != m) if (memcmp(in,ip,c->m_len+1) == 0) printf("%p %p %p %5d\n",in,ip,m,c->m_len); in++; } }#endif return UCL_E_OK;}static int bbConfig(struct ucl_compress *c, int endian, int bitsize){ if (endian != -1) { if (endian != 0) return UCL_E_ERROR; c->bb_c_endian = endian; } if (bitsize != -1) { if (bitsize != 8 && bitsize != 16 && bitsize != 32 && bitsize != 64) return UCL_E_ERROR; c->bb_c_s = bitsize; c->bb_c_s8 = bitsize / 8; } c->bb_b = 0; c->bb_k = 0; c->bb_p = NULL; c->bb_op = NULL; return UCL_E_OK;}static void bbWriteBits(struct ucl_compress *c){ uint8_t *p = c->bb_p; uint64_t b = c->bb_b; p[0] = (uint8_t)(b >> 0); if (c->bb_c_s >= 16) { p[1] = (uint8_t)(b >> 8); if (c->bb_c_s >= 32) { p[2] = (uint8_t)(b >> 16); p[3] = (uint8_t)(b >> 24); if (c->bb_c_s == 64) { p[4] = (uint8_t)(b >> 32); p[5] = (uint8_t)(b >> 40); p[6] = (uint8_t)(b >> 48); p[7] = (uint8_t)(b >> 56); } } }}static void bbPutBit(struct ucl_compress *c, unsigned bit){ assert(bit == 0 || bit == 1); assert(c->bb_k <= c->bb_c_s); if (c->bb_k < c->bb_c_s) { if (c->bb_k == 0) { assert(c->bb_p == NULL); c->bb_p = c->bb_op; c->bb_op += c->bb_c_s8; } assert(c->bb_p != NULL); assert(c->bb_p + c->bb_c_s8 <= c->bb_op); c->bb_b = (c->bb_b << 1) + bit; c->bb_k++; } else { assert(c->bb_p != NULL); assert(c->bb_p + c->bb_c_s8 <= c->bb_op); bbWriteBits(c); c->bb_p = c->bb_op; c->bb_op += c->bb_c_s8; c->bb_b = bit; c->bb_k = 1; }}static void bbPutByte(struct ucl_compress *c, unsigned b){ /**printf("putbyte %p %p %x (%d)\n", op, bb_p, x, bb_k);*/ assert(c->bb_p == NULL || c->bb_p + c->bb_c_s8 <= c->bb_op); *c->bb_op++ = (uint8_t)(b);}static void bbFlushBits(struct ucl_compress *c, unsigned filler_bit){ if (c->bb_k > 0) { assert(c->bb_k <= c->bb_c_s); while (c->bb_k != c->bb_c_s) bbPutBit(c, filler_bit); bbWriteBits(c); c->bb_k = 0; } c->bb_p = NULL;}/***********************************************************************//************************************************************************/static void code_prefix_ss11(struct ucl_compress *c, uint32_t i){ if (i >= 2) { uint32_t t = 4; i += 2; do { t <<= 1; } while (i >= t); t >>= 1; do { t >>= 1; bbPutBit(c, (i & t) ? 1 : 0); bbPutBit(c, 0); } while (t > 2); } bbPutBit(c, (unsigned)i & 1); bbPutBit(c, 1);}static voidcode_match(struct ucl_compress *c, unsigned int m_len, const unsigned int m_off){ while (m_len > c->conf.max_match) { code_match(c, c->conf.max_match - 3, m_off); m_len -= c->conf.max_match - 3; } c->match_bytes += m_len; if (m_len > c->result[3]) c->result[3] = m_len; if (m_off > c->result[1]) c->result[1] = m_off; bbPutBit(c, 0); if (m_off == c->last_m_off) { bbPutBit(c, 0); bbPutBit(c, 1); } else { code_prefix_ss11(c, 1 + ((m_off - 1) >> 8)); bbPutByte(c, (unsigned)m_off - 1); } m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); if (m_len >= 4) { bbPutBit(c,0); bbPutBit(c,0); code_prefix_ss11(c, m_len - 4); } else { bbPutBit(c, m_len > 1); bbPutBit(c, (unsigned)m_len & 1); } c->last_m_off = m_off;}static voidcode_run(struct ucl_compress *c, const uint8_t *ii, unsigned int lit){ if (lit == 0) return; c->lit_bytes += lit; if (lit > c->result[5]) c->result[5] = lit; do { bbPutBit(c, 1); bbPutByte(c, *ii++); } while (--lit > 0);}/***********************************************************************//************************************************************************/static intlen_of_coded_match(struct ucl_compress *c, unsigned int m_len, unsigned int m_off){ int b; if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -