Меню

Главная

Статистика

 

 


Ниже приведен текст программы. Как и в программе LZSS здесь есть функции побитового чтения/записи, но здесь они проще, т.к. читать и писать нужно только по одному биту. Информация о кодах символов в архиве представлена в виде таблицы чисел повторений - это не самый экономный способ, но зато самый простой. Содержательная часть начинается с первого define - я понимаю, что возможность вынести общие функции (ввод/вывод и т.п.) в отдельные файлы была бы полезна, но пока ее нет.

struct Addr word Ofs; word Seg; section void @Ptr; end void @Ptr(word Seg,Ofs) Addr P; P.Seg=Seg; P.Ofs=Ofs; return @P.Ptr; end word GetPSP() asm mov AH,62H asm int 21H asm mov AX,BX end word create(char @Name) asm push DS asm mov AH,3CH asm mov CX,00H asm mov DX,SS:[BP+6] asm mov DS,DX asm mov DX,SS:[BP+4] asm int 21H asm pop DS end word open(char @Name) asm push DS asm mov AH,3DH asm mov AL,00H asm mov DX,SS:[BP+6] asm mov DS,DX asm mov DX,SS:[BP+4] asm int 21H asm pop DS end word reset(word F) asm push DS asm mov AX,4200H asm mov BX,SS:[BP+4] asm mov CX,0 asm mov DX,0 asm int 21H asm pop DS end word read(word F; void @Buff; word N) asm push DS asm mov AH,3FH asm mov BX,SS:[BP+10] asm mov CX,SS:[BP+4] asm mov DX,SS:[BP+8] asm mov DS,DX asm mov DX,SS:[BP+6] asm int 21H asm pop DS end word write(word F; void @Buff; word N) asm push DS asm mov AH,40H asm mov BX,SS:[BP+10] asm mov CX,SS:[BP+4] asm mov DX,SS:[BP+8] asm mov DS,DX asm mov DX,SS:[BP+6] asm int 21H asm pop DS end void close(word F) asm mov AH,3EH asm mov BX,SS:[BP+4] asm int 21H end int strcmp(char @S1, @S2) int P=0; while TRUE do if S1[P]<S2[P] then return -1; end if S1[P]>S2[P] then return 1; end if S1[P]=#0 then return 0; end inc P; end end void putc(char Ch) asm mov AH,2 asm mov DL,SS:[BP+4] asm int 21H end void puts(char @St) word P=0; while St[P]!=#0 do putc(St[P]); inc P; end end struct long word lo; word hi; end void lInc(long @l) if l.lo<65535 then inc l.lo; else inc l.hi; l.lo=0; end end void lDec(long @l) if l.lo>0 then dec l.lo; else dec l.hi; l.lo=65535; end end long lSum(long a, b) asm mov AX,SS:[BP+ 4] asm mov DX,SS:[BP+ 6] asm mov BX,SS:[BP+ 8] asm mov CX,SS:[BP+10] asm add AX,BX asm db 013H ; adc DX,CX asm db 0D1H end int lCmp(long a, b) if a.hi<b.hi then return -1; end if a.hi>b.hi then return 1; end if a.lo<b.lo then return -1; end if a.lo>b.lo then return 1; end return 0; end define TXT_LEN 16384 define ARC_LEN 16384 define BLK_LEN 4096 define ARC_FWD 128 struct SNode byte Code; long Cnt; int PP; int P0; int P1; end struct SInfo byte Code; long Cnt; int Node; end SNode Tree [1024]; int Root; int nNode; int Indx [256]; void Init(long @Tabl) // построение дерева Хаффмана SInfo Info[256]; int nInfo; nInfo=0; while nInfo<256 do Info[nInfo].Code= nInfo; Info[nInfo].Cnt = Tabl[nInfo]; Info[nInfo].Node=-1; inc nInfo; end nNode=0; while nInfo>1 do int N0=0; int N1=1; if lCmp(Info[N0].Cnt,Info[N1].Cnt)<0 then N0=1; N1=0; end int I=2; while I<nInfo do if lCmp(Info[I].Cnt,Info[N0].Cnt)<0 then if lCmp(Info[I].Cnt,Info[N1].Cnt)<0 then N0=N1; N1=I; else N0=I; end end inc I; end int P0=Info[N0].Node; if P0<0 then Tree[nNode].Code = Info[N0].Code; Tree[nNode].Cnt = Info[N0].Cnt; Tree[nNode].P0 =-1; Tree[nNode].P1 =-1; Indx[Info[N0].Code]= nNode; P0 = nNode; inc nNode; end int P1=Info[N1].Node; if P1<0 then Tree[nNode].Code = Info[N1].Code; Tree[nNode].Cnt = Info[N1].Cnt; Tree[nNode].P0 =-1; Tree[nNode].P1 =-1; Indx[Info[N1].Code]= nNode; P1 = nNode; inc nNode; end dec nInfo; Info[N0].Code=Info[nInfo].Code; Info[N0].Cnt =Info[nInfo].Cnt; Info[N0].Node=Info[nInfo].Node; if N1=nInfo then N1=N0; end dec nInfo; Info[N1].Code=Info[nInfo].Code; Info[N1].Cnt =Info[nInfo].Cnt; Info[N1].Node=Info[nInfo].Node; Tree[P0] .PP = nNode; Tree[P1] .PP = nNode; Tree[nNode].Code= 0; Tree[nNode].Cnt = lSum(Tree[P0].Cnt,Tree[P1].Cnt); Tree[nNode].P0 = P0; Tree[nNode].P1 = P1; Info[nInfo].Code= 0; Info[nInfo].Cnt = Tree[nNode].Cnt; Info[nInfo].Node= nNode; inc nInfo; inc nNode; end Root=Info[0].Node; Tree[Root].PP =-1; end byte Arc [ARC_LEN]; int pArc; byte Tmp; byte pBit; void Save(word B) if pBit=0 then Arc[pArc]=Tmp; inc pArc; Tmp = 0; pBit=128; end Tmp =Tmp+pBit*B; pBit=pBit/2; end word Load() if pBit=0 then pBit=128; inc pArc; end word C=Arc[pArc]&pBit; pBit=pBit/2; return C; end void Code(int P) if Tree[P].PP>=0 then Code(Tree[P].PP); if Tree[Tree[P].PP].P0=P then Save(0); else Save(1); end end end void Encode(word hArc, hTxt) byte Txt [TXT_LEN]; // Текст long Tabl [256]; // Таблица чисел повторений int I=0; while I<256 do Tabl[I].lo=0; Tabl[I].hi=0; inc I; end int nTxt=0; int pTxt=0; while TRUE do if pTxt>=nTxt then nTxt=read(hTxt,@Txt,BLK_LEN); if nTxt=0 then exit end pTxt=0; end lInc(@Tabl[Txt[pTxt]]); inc pTxt; end write(hArc,@Tabl,1024); Init(@Tabl); reset(hTxt); nTxt=0; pTxt=0; pArc=0; while TRUE do if pTxt>=nTxt then nTxt=read(hTxt,@Txt,BLK_LEN); if nTxt=0 then exit end pTxt=0; end if pArc>=BLK_LEN then write(hArc,@Arc,pArc); pArc=0; end Code(Indx[Txt[pTxt]]); inc pTxt; end while pBit>0 do Save(0); end Save(0); if pArc>0 then write(hArc,@Arc,pArc); end end void Decode(word hArc, hTxt) long Tabl [256]; read(hArc,@Tabl,1024); Init(@Tabl); byte Txt[TXT_LEN]; int nArc=0; pArc=0; long nTxt=Tree[Root].Cnt; int pTxt=0; while nTxt.hi>0 | nTxt.lo>0 do if pTxt>=BLK_LEN then write(hTxt,@Txt,pTxt); pTxt=0; end if pArc+ARC_FWD>=nArc then word I=pArc; word J=0; while I<nArc do Arc[J]=Arc[I]; inc J; inc I; end nArc=J+read(hArc,@Arc[J],BLK_LEN); pArc=0; end int P=Root; while Tree[P].P0>=0 do if Load()=0 then P=Tree[P].P0; else P=Tree[P].P1; end end Txt[pTxt]=Tree[P].Code; inc pTxt; lDec(@nTxt); end if pTxt>0 then write(hTxt,@Txt,pTxt); end end begin char @Line=@Ptr(GetPSP(),129); // Командная строка byte @Size=@Ptr(GetPSP(),128); // Длина строки char Parm [3][128]; // Параметры int F=1; int I=0; int J=0; while I<3 do while J<Size & Line[J] =' ' do inc J; end int K=0; while J<Size & Line[J]!=' ' do Parm[I][K]=Line[J]; inc K; inc J; end Parm[I][K]=#0; if K<1 then F=0; end inc I; end word hArc; word hTxt; int C=0; if F!=0 then select case strcmp(@Parm[0][0],"e")=0 | strcmp(@Parm[0][0],"E")=0: hArc=create(@Parm[1][0]); hTxt=open (@Parm[2][0]); C=1; case strcmp(@Parm[0][0],"d")=0 | strcmp(@Parm[0][0],"D")=0: hArc=open (@Parm[1][0]); hTxt=create(@Parm[2][0]); C=2; end end if C=0 then puts("huffman.com e(ncode)|d(ecode) arc-file txt-file"); return end Tmp = 0; pBit=128; select case C=1: Encode(hArc,hTxt); case C=2: Decode(hArc,hTxt); end close(hTxt); close(hArc); end

Назад

создание сайта. скачать бесплатно без регистрации навигатор на nokia n73. образец договора на консалтинговые услуги