Subversion Repositories Kolibri OS

Rev

Rev 109 | Blame | Last modification | View Log | Download | RSS feed

  1. ; @RCHER main algorythm
  2. ; Written in pure assembler by Ivushkin Andrey aka Willow
  3.  
  4. macro get_a _type,_size,c1,c2,c3,c4,c5
  5. {
  6. get_#_type:
  7. local .no,.no0,.ex
  8.     push edx
  9.     and  [Flags],not 1
  10. if _type eq Len
  11.     cmp  eax,c4
  12.     jne   .no
  13.     mov  eax,c5
  14.     jmp  .ex
  15.    .no:
  16. end if
  17.     sub  eax,c1
  18.     ja   .no0
  19.     add  eax,c2
  20.     jmp  .ex
  21.    .no0:
  22.     add  eax,c3
  23.     push eax
  24.     mov  ecx,eax
  25.     shr  ecx,_size
  26.     xor  eax,eax
  27.     call read_bits
  28.     pop  edx
  29.     and  edx,1 shl _size-1
  30.     shl  edx,cl
  31.     movzx ecx,[tblH#_type+ecx*2]
  32.     add  edx,ecx
  33.     add  eax,edx
  34.    .ex:
  35.     or  [Flags],1
  36.     pop  edx
  37.     ret
  38. }
  39. ; *************************
  40.  
  41. Deflate:
  42.     mov  edi,[outp]
  43.   .init:
  44.     mov  [bits],8
  45.     lodsb
  46.     call setcurb
  47.   .blkbegin:
  48.     and  [lastblk],0
  49.     and  [Flags],not 1
  50.     rbits 0,1
  51.     test eax,eax
  52.     je  .nolast
  53.     mov  [lastblk],1
  54.   .nolast:
  55.     rbits 0,2
  56.     cmp  eax,10b
  57.     je   .DynHuff
  58.     cmp  eax,01b
  59.     je   .static
  60.     test eax,eax
  61.     jnz  .errorID
  62.     Msg  30
  63.     movzx ecx,[bits]
  64.     call read_bits
  65.     movzx ecx,word[esi-1]
  66.     add  esi,3
  67.     rep  movsb
  68.     jmp  .check_last
  69.   .errorID:
  70.     Msg  6
  71.     ret
  72. ; Static Huffman
  73.   .static:
  74. if SHOW_METH eq 1
  75.     Msg  20
  76. end if
  77.     mov  edi,[outp]
  78.     or  [Flags],1
  79.   .next:
  80.     rbits 0,7
  81. ;    stop
  82.     cmp  eax,0x17
  83.     ja   .no7
  84.     add  eax,256
  85.     cmp  eax,256
  86.     jne  .noend
  87.   .check_last:
  88.     mov  [outp],edi
  89.     cmp  [lastblk],1
  90.     je   .ex
  91.     jmp  .blkbegin
  92.    .noend:
  93.     call get_Len
  94.     mov  ebx,eax
  95.     rbits 0,5
  96.     call get_Dist
  97.     neg  eax
  98.     push esi
  99.     lea  esi,[edi+eax]
  100.     mov  ecx,ebx
  101.     rep  movsb
  102.     pop  esi
  103.     jmp  .next
  104.    .no7:
  105.     rbits eax,1
  106.     cmp  eax,0xc8
  107.     jb   .no9
  108.     rbits eax,1
  109.     sub  eax,0xd0
  110.     jmp  .no81
  111.   .no9:
  112.     cmp  eax,0xc0
  113.     jb   .no81
  114.     add  eax,0x58
  115.     jmp  .noend
  116.   .no81:  
  117.     sub  eax,0x30
  118.     stosb
  119.     jmp .next
  120.   .ex:
  121.     ret
  122. ; ************* dynamic Huffman ************
  123.  
  124. .DynHuff:
  125. ;    dps  '##'
  126. if SHOW_METH eq 1
  127.     Msg  19
  128. end if
  129.     pusha
  130.     xor  eax,eax
  131.     mov  ecx,(area-bl_count) / 4
  132.     mov  edi,bl_count
  133.     rep  stosd
  134.     popa
  135.  
  136. ; max_len=0
  137.     and  [max_len],0
  138.     rbits 0,5
  139. ; hlit-257
  140.     add  eax,257
  141.     mov  [hlit],ax
  142.     rbits 0,5
  143. ; hdist-1
  144.     inc  eax
  145.     mov  [hdist],al
  146.     rbits 0,4
  147. ; hclen-4
  148.     add  eax,4
  149.     mov  [hclen],al
  150.     mov  ecx,eax
  151.     push edi
  152.     mov  edi,tmp_clit
  153. ; read  code lengths for code lengths
  154.   .alphloop:
  155.     push ecx
  156.     rbits 0,3
  157.     stosb
  158.     pop  ecx
  159.     loop .alphloop
  160. ; sort code lengths for code lengths
  161.     push esi
  162.     movzx ecx,[hclen]
  163.     xor  eax,eax
  164.     mov  edi,tmp_clit
  165.     mov  esi,tblSort
  166.   .sortloop:
  167.     lodsb
  168.     movzx bx,byte[edi]
  169.     mov  [sorted_clit+eax*2],bx
  170.     inc  edi
  171.     loop .sortloop
  172.     pop  esi edi
  173. .generate:
  174.     mov  ecx,19
  175.     mov  ebx,calph
  176.     mov  edx,seql
  177.     mov  eax,sorted_clit
  178.     call Huffc
  179.     and  [tblCount],0
  180.     or  [Flags],1
  181.     mov  edi,Lit_c
  182.     mov  ebp,sorted_clit
  183.    .again:
  184.     cmp  edi,output+OUTBUF
  185.     jb   ._ok
  186.     Msg  16
  187.     jmp  .ex
  188.   ._ok:
  189.     mov  edx,seql
  190.     mov  ebx,calph
  191.     call get_code
  192.     call ExpLen
  193.     cmp  [hlit],ax
  194.     ja   .again
  195. if SHOW_CHARS eq 1
  196.     mov  edi,Lit_c
  197.     call Show_codes
  198. end if
  199.     mov  edi,Dist_c
  200.     and  [tblCount],0
  201.    .again2:
  202.     mov  ebx,calph
  203.  
  204.     call get_code
  205.     call ExpLen
  206.     cmp  [hdist],al
  207.     ja   .again2
  208.     movzx ecx,[hlit]
  209.     mov  ebx,Literal
  210.     mov  edx,seql
  211.     mov  eax,Lit_c
  212.     call Huffc
  213.     movzx ecx,[hdist]
  214.     mov  ebx,Distance
  215.     mov  edx,seqd
  216.     mov  eax,Dist_c
  217.     call Huffc
  218.  
  219.     push [hlit]
  220.     pop  [tblLen]
  221.     mov  ebp,Lit_c
  222.     mov  edx,seql
  223.     mov  ebx,Literal
  224.     mov  edi,[outp]
  225.     and  [tblCount],0
  226.   .again3:               ; <------------
  227.     call get_code
  228.     cmp  eax,256
  229.     je   .check_last
  230.     ja   .dist
  231.     stosb
  232.     jmp  .again3
  233.   .dist:
  234.     call get_Len
  235.     push eax ebx edx ebp
  236.     mov  ecx,32
  237.     mov  ebp,Dist_c
  238.     mov  edx,seqd
  239.     mov  ebx,Distance
  240.     mov  [tblLen],32
  241.     call get_code
  242.     call get_Dist
  243.     push [hlit]
  244.     pop  [tblLen]
  245.     neg  eax
  246.     pop  ebp edx ebx ecx
  247.     push esi
  248.     lea  esi,[edi+eax]
  249.     rep  movsb
  250.     pop  esi
  251.     jmp  .again3
  252.  
  253. ; ******************************************
  254. Huffc:
  255. ; EBX - dest array, ECX - length, EDX - br_seq dest, EAX - source array
  256.     push esi edi eax ecx
  257.     mov  edi,bl_count
  258.     xor  eax,eax
  259.     mov  ecx,BITS
  260.     rep  stosw
  261.     pop  ecx
  262.     mov  esi,[esp]
  263.     mov  [tblLen],cx
  264.     mov  [max_len],ax
  265. ; Count the number of codes for each code length
  266.   .cnt_loop:
  267.     lodsw
  268.     cmp  [max_len],ax
  269.     jae  .skip
  270.     mov  [max_len],ax
  271.   .skip:
  272.     inc  byte[bl_count+eax]
  273.     loop .cnt_loop
  274.     movzx ecx,[max_len]
  275.     xor  eax,eax
  276.     and  [bl_count],al
  277.     xor  esi,esi   ; edx - bits
  278.     mov  edi,next_code+2
  279.     push ebx
  280. ; Find the numerical value of the smallest code for each code length
  281.   .nc_loop:
  282.     movzx bx,byte[bl_count+esi]
  283.     add  ax,bx
  284.     shl  ax,1
  285.     stosw
  286.     inc  esi
  287.     loop .nc_loop
  288.     pop  ebx
  289. ; clear table
  290.     movzx ecx,[tblLen]
  291.     xor  eax,eax
  292.     dec  eax
  293.     mov  edi,ebx
  294.     rep  stosw
  295.     inc  eax
  296.     movzx ecx,[tblLen]
  297.     mov  esi,[esp]
  298.     mov  edi,ebx
  299. ; Assign numerical values to all codes
  300.   .loop3:
  301.     lodsw
  302.     test eax,eax
  303.     jz   .lp
  304.     push [next_code+eax*2]
  305.     pop  word[edi]
  306.     inc  [next_code+eax*2]
  307.   .lp:
  308.     add  edi,2
  309.     loop .loop3
  310. ; Clear all codes
  311.     xor  eax,eax
  312.     mov  edi,edx
  313.     movzx ecx,[max_len]
  314.     mov  [edi-1],al
  315. ; Prepare read bit sequences
  316.   .rebiloop:
  317.     inc  eax
  318.     cmp  [bl_count+eax],0
  319.     jz   .sk
  320.     stosb
  321.     inc  byte[edx-1]
  322.   .sk:
  323.     loop .rebiloop
  324.     movzx ecx,byte[edx-1]
  325.     dec  ecx
  326.     jecxz .noreb2
  327.   .reb2loop:
  328.     mov  al,[edx+ecx-1]
  329.     sub  [edx+ecx],al
  330.     loop .reb2loop
  331.   .noreb2:
  332.     pop  eax edi esi
  333.     ret
  334.  
  335. ; ******************************************
  336.  
  337. ; get Codes of variable sizes
  338. get_code:
  339. ; EDX - br_seq, EBX - source table, EBP - codelength table
  340.     push edx edi
  341.     xor  eax,eax
  342.     movzx ecx,byte[edx-1]
  343.     mov  [codel],ax
  344.    .rb3:
  345.     push ecx
  346.     movzx ecx,byte[edx]
  347.     add  [codel],cx
  348.     call read_bits
  349.     movzx ecx,[tblLen]
  350.     inc  ecx
  351.     mov  edi,ebx
  352.    .scas:
  353.     repne scasw
  354.     jecxz .notfound
  355.     push edi ecx
  356.     sub  edi,ebx
  357.     sub  edi,2
  358.     mov  cx,[codel]
  359.     cmp  cx,[ds:ebp+edi]
  360.     jne  .notfound2
  361.     mov  eax,edi
  362.     shr  eax,1
  363.     add  esp,12
  364.    .pp:
  365.     pop  edi edx
  366.     ret
  367.    .notfound2:
  368.     pop  ecx
  369.     pop  edi
  370.     jmp  .scas
  371.    .notfound:
  372.     pop  ecx
  373.     inc  edx
  374.     loop .rb3
  375.     Msg  7
  376.     jmp  .pp
  377.  
  378. codel dw ?
  379. ; ******************************************
  380. ExpLen:
  381.     cmp  eax,16
  382.     jae  .noliteral
  383.     inc  [tblCount]
  384.     stosw
  385.     jmp  .nomatch
  386.   .noliteral:
  387.     and  [Flags],not 1
  388.     mov  ebx,3
  389.     cmp  eax,17
  390.     jae  .code1718
  391.     mov  ecx,2
  392.     xor  eax,eax
  393.     call read_bits
  394.     lea  ecx,[eax+ebx]
  395.     mov  ax,[edi-2]
  396.   .cc:
  397.     add  [tblCount],cx
  398.     rep  stosw
  399.     or  [Flags],1
  400.     jmp  .nomatch
  401.   .code1718:
  402.     jne  .code18
  403.     mov  ecx,3
  404.   .cc2:
  405.     xor  eax,eax
  406.     call read_bits
  407.     lea  ecx,[eax+ebx]
  408.     xor  eax,eax
  409.     jmp  .cc
  410.   .code18:
  411.     mov  ebx,11
  412.     mov  ecx,7
  413.     jmp  .cc2
  414.   .nomatch:
  415.     mov  ax,[tblCount]
  416.     ret
  417. get_a Len,2,256+8,10,3,285,258
  418. get_a Dist,1,3,4,1
  419.  
  420.  
  421. ; ******************************************
  422. read_bits: ; eax-dest; ecx-count
  423.     push edx ecx
  424.   .shift:
  425.   if RBLOCK eq 4
  426.     ror  [cur_byte],1
  427.   else
  428.     ror  byte[cur_byte],1
  429.   end if
  430.     pushf
  431.     test [Flags],1
  432.     je   .noh1
  433.     popf
  434.     rcl  eax,1
  435.     jmp  .dec
  436.   .noh1:
  437.     popf
  438.     rcr  eax,1
  439.   .dec:
  440.     dec  [bits]
  441.     jnz  .loop1
  442.   .push:
  443.     push eax
  444.     mov  eax,[esi]
  445.     call setcurb
  446.     pop  eax
  447.   if RBLOCK eq 1
  448.     inc  esi
  449.     inc  [IDATcount]
  450.   else
  451.     inc  esi
  452.     inc  [IDATcount]
  453.   end if
  454.     cmp  esi,area+INBUF-BSIZE
  455.     jbe   .ok
  456.     pusha
  457. if SHOW_RBLOCK eq 1
  458.     Msg  9
  459. end if
  460.     mov  eax,0
  461.     mov  ebx,1
  462.     call FileSeek
  463.     mov  [esp+4],esi
  464.     popa
  465.   .ok:
  466.     test [Flags],PNG_MODE
  467.     jz   .idatok
  468.     mov  edx,[IDATcount]
  469.     cmp  edx,[IDATsize]
  470.     jbe  .idatok
  471.     pusha
  472.     lodsd
  473.     call PngParse.nxt_sec
  474.     mov  [IDATcount],1
  475.     mov  [esp+4],esi
  476.     mov  [esp+20],edx
  477.     popa
  478.     cmp  edx,21
  479.     jne  .idatok
  480.     mov  eax,256
  481.     pop  ecx
  482.     jmp  .exx
  483.   .idatok:
  484.  
  485.     mov  [bits],8
  486.   .loop1:
  487.     loop .shift2
  488.     jmp  .popc
  489.   .shift2:
  490.     jmp  .shift
  491.   .popc:
  492.     pop  ecx
  493.     test [Flags],1
  494.     jne  .exx
  495.   .noh2:
  496.     rol  eax,cl
  497.   .exx:
  498.     pop  edx
  499.     ret
  500.  
  501. if SHOW_CHARS eq 1
  502. Show_codes:
  503.     pusha
  504.     movzx ecx,[tblLen]
  505.     mov ecx,256
  506.     xor  eax,eax
  507.   .lp2:
  508.     mov  [braces+1],al
  509.     push eax ecx
  510.     invoke StrFormat,eax,strbuf,20
  511.     invoke WriteConsole,[cons],strbuf,16,param1,NULL
  512.     invoke WriteConsole,[cons],braces,6,param1,NULL
  513.     mov  eax,[esp+4]
  514.     movzx  eax,word[edi+eax*2]
  515.     test eax,eax
  516.     jz     .skip
  517.     invoke WriteConsole,[cons],exist,6,param1,NULL
  518.   .skip:
  519.     invoke WriteConsole,[cons],braces+6,2,param1,NULL
  520.     pop  ecx eax
  521.     inc  eax
  522.     loop .lp
  523.     jmp  .ex
  524.    .lp:
  525.     jmp  .lp2
  526.    .ex:
  527.     popa
  528.     ret
  529.  
  530.     cons dd ?
  531.     param1 dd ?
  532.     braces db '( ) = ',0xa, 0xd
  533.     strbuf rb 20
  534.     exist db 'exists'
  535. end if
  536.  
  537. makeCRC:
  538.     pusha
  539.     Msg  8
  540.     mov  edi,CRC32table
  541.     add  edi,255*4
  542.     std
  543.     mov  ecx,255
  544.     mov  ebx,0xedb88320
  545.   .m1:
  546.     mov  eax,ecx
  547.     push ecx
  548.     mov  ecx,8
  549.   .m2:
  550.     shr  eax,1
  551.     jnc  .m3
  552.     xor  eax,ebx
  553.   .m3:
  554.     loop .m2
  555.     pop  ecx
  556.     stosd
  557.     loop .m1
  558.     popa
  559.     cld
  560.     ret
  561.  
  562. UCRC:
  563. ; in:  esi - data to calculate CRC
  564. ;      ecx - its length
  565. ;      [CRC32] - previous CRC32
  566. ; out: [CRC32]- partial CRC32 (no pre- & post-conditioning!)
  567.     pusha
  568.     cmp  dword[CRC32table+4],0x77073096
  569.     je   .tbl_rdy
  570.     call makeCRC
  571.   .tbl_rdy:
  572.     mov  eax,[CRC32]
  573.     not  eax
  574.   .m1:
  575.     movzx ebx,al
  576.     shr  eax,8
  577.     xor  bl,[esi]
  578.     xor  eax,[CRC32table+ebx*4]
  579.     inc  esi
  580.     loop .m1
  581.     not  eax
  582.     mov  [CRC32],eax
  583.     popa
  584.     ret
  585.  
  586. UAdler:
  587. ; in:  esi - data to calculate CRC
  588. ;      ecx - its length
  589. ;      [Adler32] - previous Adler32
  590. ; out: [Adler32]- partial Adler32
  591.     pusha
  592.     mov  ebp,65521
  593.     movzx ebx,word[Adler32] ; s1-ebx
  594.     movzx edi,word[Adler32+2] ; s2-edi
  595.   .m1:
  596.     movzx eax,byte[esi]
  597.     add  eax,ebx
  598.     xor  edx,edx
  599.     div  ebp
  600.     mov  ebx,edx
  601.     lea  eax,[edi+ebx]
  602.     xor  edx,edx
  603.     div  ebp
  604.     mov  edi,edx
  605.     inc  esi
  606.     loop .m1
  607.     shl  edi,16
  608.     add  edi,ebx
  609.     mov  [Adler32],edi
  610.     popa
  611.     ret
  612.  
  613. tblSort db 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
  614. tblHLen dw 7,11,19,35,67,131
  615. tblHDist dw 3,5,9,17,33,65,129,257,513,1025,2049,4097,8193,16385
  616.