⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 open arj source
💻 C
📖 第 1 页 / 共 3 页
字号:
   putbits(CBIT, 0);   putbits(CBIT, root);  }  root=make_tree(NP, p_freq, pt_len, (unsigned short FAR *)pt_code);  if(root>=NP)   write_pt_len(NP, PBIT, -1);  else  {   putbits(PBIT, 0);   putbits(PBIT, root);  }  pos=0;  for(i=0; i<size; i++)  {   if(unpackable)    return;   if(i%CHAR_BIT==0)    flags=buf[pos++];   else    flags<<=1;   if(flags&(1U<<(CHAR_BIT-1)))   {    c=(unsigned int)buf[pos++]+(1<<CHAR_BIT);    encode_c(c);    k=buf[pos++];    k|=(unsigned int)buf[pos++]<<CHAR_BIT;    encode_p(k);   }   else   {    c=buf[pos++];    encode_c(c);   }  }  for(i=0; i<NC; i++)   c_freq[i]=0;  for(i=0; i<NP; i++)   p_freq[i]=0; }}/* Handy macro for retrieval of two bytes (don't care about the portability) */#ifdef ALIGN_POINTERS #define word_ptr(c) (  (((unsigned char *) (c))[0]<<8)+ ((unsigned char *) (c))[1] ) #define _diff(c1,c2) ( (c1)[0]!=(c2)[0] || (c1)[1]!=(c2)[1] )#elif !defined(TILED) #define word_ptr(c) (*(unsigned short *)(c))#endif/* Tree update routine. Possibly the most time-consuming one. */static int upd_tree(int n_c){ #ifdef ASM8086  asm{                push    bp                push    si                push    di                mov     si, n_c                mov     bp, 1                mov     es, word ptr dtree+2                mov     bx, si                mov     bx, es:[bx+si]                or      bx, bx                jl      done_dup  }ok:  asm{                mov     di, tree                add     si, di                add     di, bx                mov     ax, [si]                cld                mov     dx, numchars                dec     dx                jge     ut_loop  }done_dup:  asm{                jmp     done  }ut_fetch:  asm{                mov     ax, [bp+si-1]  }select_pos:  asm{                mov     di, tree                add     di, bp  }ut_loopbody:  asm{                dec     dx                jl      ut_brk                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                jz      ut_rcount                dec     dx                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                je      ut_rcount                dec     dx                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                je      ut_rcount                dec     dx                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                je      ut_rcount                dec     dx                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                je      ut_rcount                dec     dx                shl     bx, 1                mov     bx, es:[bx]                or      bx, bx                jl      ut_brk                cmp     ax, [bx+di-1]                je      ut_rcount                jmp     short ut_loopbody  }ut_brk:  asm{                jmp     short upd_finish  }ut_rcount:  asm{                sub     di, bp                add     di, bx  }ut_loop:  asm{                mov     cx, [si]                cmp     cx, [di]                jnz     select_pos                mov     ax, ds                mov     es, ax                mov     ax, di                add     di, 2                add     si, 2                mov     cx, 128                repe cmpsw                mov     cl, [di-2]                sub     cl, [si-2]                xchg    ax, di                sub     ax, di                sub     si, ax                sub     cl, 1                adc     ax, -2                mov     es, word ptr dtree+2                cmp     ax, bp                jg      verify_pos                jmp     ut_fetch  }verify_pos:  asm{                mov     cx, si                sub     cx, di                cmp     cx, dicsiz_cur                jg      upd_finish                dec     cx                mov     dicpos, cx                mov     bp, ax                cmp     bp, 256                jge     upd_finish                jmp     ut_fetch  }upd_finish:  asm{                cmp     bp, 256                jle     done                mov     bp, 256  }done:  asm{                mov     ax, bp                mov     tc_passes, ax                pop     di                pop     si                pop     bp  }  return(tc_passes); #else short FAR *dptr; short r_bx, r_dx; unsigned short r_ax; short r_bp=1; unsigned char *tptr; unsigned char *tdptr; unsigned char *prev_tptr, *prev_tdptr; int c; char diff; int remainder; dptr=dtree; if((r_bx=dptr[n_c])>=0) {  tptr=tree+n_c;  tdptr=tree+r_bx;  r_ax=word_ptr(tptr);  r_dx=numchars;  if(--r_dx>=0)   goto ut_loop;ut_fetch:  r_ax=word_ptr(tptr+r_bp-1);select_pos:  tdptr=tree+r_bp;  do  {   if(--r_dx<0)    goto upd_finish;   r_bx=dptr[r_bx];   if(r_bx<0)    goto upd_finish;  } while(r_ax!=word_ptr(tdptr+r_bx-1));  tdptr+=r_bx-r_bp;ut_loop:  #ifdef ALIGN_POINTERS  if (_diff(tptr,tdptr))  #else    if(word_ptr(tptr)!=word_ptr(tdptr))  #endif   goto select_pos;  prev_tptr=tptr;  prev_tdptr=tdptr;  tptr+=2;  tdptr+=2;  for(c=128; c>0; c--)  {   #ifdef ALIGN_POINTERS   if (_diff(tptr,tdptr))   #else     if(word_ptr(tptr)!=word_ptr(tdptr))   #endif    break;   tptr+=2;   tdptr+=2;  }  diff=*(tdptr)-*(tptr);  remainder=tdptr-prev_tdptr;  if(diff==0)   remainder+=1;  tptr=prev_tptr;  tdptr=prev_tdptr;  if(remainder<=r_bp)   goto ut_fetch;  if(tptr-tdptr<=dicsiz_cur)  {   dicpos=tptr-tdptr-1;   r_bp=remainder;   if(r_bp<256)    goto ut_fetch;  }upd_finish:  if(r_bp>256)   r_bp=256; } return(tc_passes=r_bp); #endif}/* Optimized output routine */static void output(int c, unsigned short p){ unsigned char FAR *bptr; unsigned char cy; unsigned short r_dx; unsigned short r_bx; bptr=buf; r_dx=cpos; cy=output_mask&1; output_mask=(cy?0x80:0)|((output_mask&0xFF)>>1); if(cy) {  if(r_dx>=bufsiz)  {   send_block();   if(unpackable)   {    cpos=bptr-buf;    return;   }   r_dx=0;  }  output_pos=r_dx;  buf[r_dx]=0;  r_dx++; } bptr+=r_dx; *bptr++=c; c_freq[c]++; if(c>=256) {  buf[output_pos]|=output_mask;  *bptr++=p&0xFF;  *bptr++=(p>>8);  for(r_bx=0; p!=0; p>>=1)   r_bx++;  p_freq[r_bx]++; } cpos=bptr-buf;}/* Unstubbed optimized output routine */static void output_opt(unsigned char c){ unsigned char FAR *bptr, FAR *cptr; unsigned short r_dx; unsigned char cy; cptr=bptr=buf; r_dx=cpos; cy=output_mask&1; output_mask=(cy?0x80:0)|((output_mask&0xFF)>>1); if(cy) {  if(r_dx>=bufsiz)  {   send_block();   r_dx=0;   if(unpackable)   {    cpos=r_dx;    return;   }  }  output_pos=r_dx;  cptr[r_dx]=0;  r_dx++; } bptr+=r_dx; *bptr++=c; c_freq[c]++; cpos=bptr-cptr;}/* Initializes memory for encoding */void allocate_memory(){ int i; if((c_freq=calloc(NC*2-1, sizeof(*c_freq)))==NULL)  error(M_OUT_OF_NEAR_MEMORY); if((c_code=farcalloc(NC, sizeof(*c_code)))==NULL)  error(M_OUT_OF_MEMORY); if((heap=farcalloc(NC+1, sizeof(*heap)))==NULL)  error(M_OUT_OF_MEMORY); for(i=0; i<NP; i++)  p_freq[i]=0; depth=0; bufsiz=current_bufsiz; if(bufsiz>=MAX_BUFSIZ-BUFSIZ_INCREMENT)  bufsiz=MAX_BUFSIZ-1; #ifdef FINETUNE_BUFSIZ  i=1; #endif /* Adjust the buffer size if there's not enough memory for it */ while((buf=farmalloc(bufsiz))==NULL) {  #ifndef FINETUNE_BUFSIZ   bufsiz=bufsiz/10U*9U;  #else   if(i<2048)    bufsiz-=i++;   else    bufsiz=bufsiz/16U*15U;  #endif  if(bufsiz<MIN_BUFSIZ)   error(M_OUT_OF_MEMORY); } if(debug_enabled&&strchr(debug_opt, 'v')!=NULL)  msg_cprintf(0, M_BUFSIZ, bufsiz); init_putbits(); output_mask=1; output_pos=0; cpos=0; buf[output_pos]='\0'; bufsiz-=30;}/* Shutdown the encoding */void NEAR huf_encode_end(){ if(!unpackable)  send_block(); shutdown_putbits(); free(c_freq); farfree(c_code); farfree(heap); farfree(buf); bufsiz=0; cpos=0;}/* Basic encoding routine */static void NEAR huf_encode(){ int hash_bits; unsigned short fp_max; int nchars; int i, j, m=0; short k, l; unsigned short t;                      /* Exchange variable */ int tree_el; unsigned int n_passes; unsigned int f_dicpos; unsigned int fetch; unsigned int max_fetch;                /* For comparision */ short FAR *fptr; short FAR *dtptr; unsigned char *tptr; unsigned short r_cx, r_dx, r_ax; int pm; hash_bits=(dicbit+2)/3; fpcount=1U<<dicbit; fp_max=fpcount-1; if(tree==NULL) {  if((tree=calloc(treesize+2, sizeof(*tree)))==NULL)   error(M_OUT_OF_NEAR_MEMORY);  #ifdef ASM8086   ftree=farcalloc_based((unsigned long)treesize+16L, sizeof(*ftree));   dtree=(FP_OFF(ftree)==0)?ftree:MK_FP(FP_SEG(ftree)+((FP_OFF(ftree)+15)>>4), 0);  #else   ftree=dtree=farcalloc((unsigned long)treesize+16L, sizeof(*ftree));  #endif  fpbuf=farcalloc((unsigned long)fpcount+4L, 2L);  if(ftree==NULL||fpbuf==NULL)   error(M_OUT_OF_MEMORY); } if(dic_alloc<1024)  dic_alloc=1024; allocate_memory(); nchars=(UCHAR_MAX+THRESHOLD)*2; display_indicator(0L); encoded_bytes=0L; tc_passes=0; dicpos=0; i=j=0; while(!unpackable) {  tree_el=0;  k=0;  if(j!=0)  {   tree_el=dic_alloc;   if((k=j-tree_el)<=0)   {    k=0;    tree_el=j;   }   else    memmove(tree, tree+k, tree_el);  }  max_fetch=fetch=(unsigned int)(treesize-tree_el);  if(multivolume_option)   fetch=check_multivolume(fetch);  if(max_fetch!=fetch)   nchars=4;  if((fetch=fetch_uncomp(tree+tree_el, fetch))==0)  {   if(tree_el==0||k==0)    break;   memmove(tree+k, tree, tree_el);   dicsiz_cur=min(tree_el-i-1, dicsiz_cur);   break;  }  j=fetch+tree_el;  encoded_bytes+=(unsigned long)fetch;  display_indicator(encoded_bytes);  m=0;  if(k<=0)   fill_fpbuf();  else  {   fptr=fpbuf;   for(l=fpcount>>2; l>0; l--)   {    *fptr=max(*fptr-k, -1);    fptr++;    *fptr=max(*fptr-k, -1);    fptr++;    *fptr=max(*fptr-k, -1);    fptr++;    *fptr=max(*fptr-k, -1);    fptr++;   }   dtptr=dtree;   for(l=tree_el>>3; l>0; l--)   {    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;    *dtptr=max(dtptr[k]-k, -1);    dtptr++;   }   /* Store the remainder */   for(l=tree_el%8; l>0; l--)   {    *dtptr=max(dtptr[k]-k, -1);    dtptr++;   }   m+=tree_el;   if(m>=2)    m-=2;  }  tptr=&tree[m];  r_dx=(unsigned short)*(tptr++);  r_cx=(fp_max&0xFF00)|(hash_bits&0xFF);  r_dx<<=(hash_bits&0xFF);  r_dx^=(unsigned short)*(tptr++);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -