Subversion Repositories Kolibri OS

Rev

Rev 837 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 1066 $
  9.  
  10.  
  11. ; void __stdcall unpack(void* packed_data, void* unpacked_data);
  12. unpack:
  13.         pushad
  14.         mov     esi, [esp+32+4]
  15.         mov     edi, [esp+32+8]
  16.         mov     eax, [esi+8]
  17.         and     al, 0xC0
  18.         cmp     al, 0xC0
  19.         jz      .failed
  20.         mov     eax, [esi+8]
  21.         push    eax
  22.         add     esi, 12
  23.         and     al, not 0xC0
  24.         dec     eax
  25.         jz      .lzma
  26. .failed:
  27.         pop     eax
  28.         popad
  29.         ret     8
  30. .lzma:
  31.         pushfd
  32.         cli
  33.         call    .lzma_unpack
  34.         popfd
  35.  
  36. .common:
  37.         pop     eax
  38.         test    al, 0x80
  39.         jnz     .ctr1
  40.         test    al, 0x40
  41.         jz      .ok
  42.         lodsd
  43.         mov     ecx, eax
  44.         jecxz   .ok
  45.         mov     dl, [esi]
  46.         mov     esi, [esp+32+8]
  47. .c1:
  48.         lodsb
  49.         sub     al, 0E8h
  50.         cmp     al, 1
  51.         ja      .c1
  52.         cmp     byte [esi], dl
  53.         jnz     .c1
  54.         lodsd
  55. ; "bswap eax" is not supported on i386
  56.         shr     ax, 8
  57.         ror     eax, 16
  58.         xchg    al, ah
  59.         sub     eax, esi
  60.         add     eax, [esp+32+8]
  61.         mov     [esi-4], eax
  62.         loop    .c1
  63. .ok:
  64.         popad
  65.         ret     8
  66. .ctr1:
  67.         lodsd
  68.         mov     ecx, eax
  69.         jecxz   .ok
  70.         mov     dl, [esi]
  71.         mov     esi, [esp+32+8]
  72. .c2:
  73.         lodsb
  74. @@:
  75.         cmp     al, 0xF
  76.         jnz     .f
  77.         lodsb
  78.         cmp     al, 80h
  79.         jb      @b
  80.         cmp     al, 90h
  81.         jb      @f
  82. .f:
  83.         sub     al, 0E8h
  84.         cmp     al, 1
  85.         ja      .c2
  86. @@:
  87.         cmp     byte [esi], dl
  88.         jnz     .c2
  89.         lodsd
  90.         shr     ax, 8
  91.         ror     eax, 16
  92.         xchg    al, ah
  93.         sub     eax, esi
  94.         add     eax, [esp+32+8]
  95.         mov     [esi-4], eax
  96.         loop    .c2
  97.         jmp     .ok
  98.  
  99. .lzma_unpack:
  100.  
  101. .pb     =       2       ; pos state bits
  102. .lp     =       0       ; literal pos state bits
  103. .lc     =       3       ; literal context bits
  104. .posStateMask   =       ((1 shl .pb)-1)
  105. .literalPosMask =       ((1 shl .lp)-1)
  106.  
  107. .kNumPosBitsMax =       4
  108. .kNumPosStatesMax =     (1 shl .kNumPosBitsMax)
  109.  
  110. .kLenNumLowBits         =       3
  111. .kLenNumLowSymbols      =       (1 shl .kLenNumLowBits)
  112. .kLenNumMidBits         =       3
  113. .kLenNumMidSymbols      =       (1 shl .kLenNumMidBits)
  114. .kLenNumHighBits        =       8
  115. .kLenNumHighSymbols     =       (1 shl .kLenNumHighBits)
  116.  
  117. .LenChoice      =       0
  118. .LenChoice2     =       1
  119. .LenLow         =       2
  120. .LenMid         =       (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits))
  121. .LenHigh        =       (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits))
  122. .kNumLenProbs   =       (.LenHigh + .kLenNumHighSymbols)
  123.  
  124. .kNumStates     =       12
  125. .kNumLitStates  =       7
  126. .kStartPosModelIndex =  4
  127. .kEndPosModelIndex =    14
  128. .kNumFullDistances =    (1 shl (.kEndPosModelIndex/2))
  129. .kNumPosSlotBits =      6
  130. .kNumLenToPosStates =   4
  131. .kNumAlignBits  =       4
  132. .kAlignTableSize =      (1 shl .kNumAlignBits)
  133. .kMatchMinLen   =       2
  134.  
  135. .IsMatch        =       0
  136. .IsRep          =       (.IsMatch + (.kNumStates shl .kNumPosBitsMax))
  137. .IsRepG0        =       (.IsRep + .kNumStates)
  138. .IsRepG1        =       (.IsRepG0 + .kNumStates)
  139. .IsRepG2        =       (.IsRepG1 + .kNumStates)
  140. .IsRep0Long     =       (.IsRepG2 + .kNumStates)
  141. .PosSlot        =       (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax))
  142. .SpecPos        =       (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits))
  143. .Align_         =       (.SpecPos + .kNumFullDistances - .kEndPosModelIndex)
  144. .Lencoder       =       (.Align_ + .kAlignTableSize)
  145. .RepLencoder    =       (.Lencoder + .kNumLenProbs)
  146. .Literal        =       (.RepLencoder + .kNumLenProbs)
  147.  
  148. .LZMA_BASE_SIZE =       1846    ; must be ==Literal
  149. .LZMA_LIT_SIZE  =       768
  150.  
  151. .kNumTopBits    =       24
  152. .kTopValue      =       (1 shl .kNumTopBits)
  153.  
  154. .kNumBitModelTotalBits =        11
  155. .kBitModelTotal =       (1 shl .kNumBitModelTotalBits)
  156. .kNumMoveBits   =       5
  157.  
  158.         push    edi
  159. ; int state=0;
  160.         xor     ebx, ebx
  161.         mov     [.previousByte], bl
  162. ; unsigned rep0=1,rep1=1,rep2=1,rep3=1;
  163.         mov     eax, 1
  164.         mov     edi, .rep0
  165.         stosd
  166.         stosd
  167.         stosd
  168.         stosd
  169. ; int len=0;
  170. ; result=0;
  171.         mov     ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp))
  172.         mov     eax, .kBitModelTotal/2
  173.         mov     edi, [.p]
  174.         rep     stosd
  175. ; RangeDecoderInit
  176. ; rd->ExtraBytes = 0
  177. ; rd->Buffer = stream
  178. ; rd->BufferLim = stream+bufferSize
  179. ; rd->Range = 0xFFFFFFFF
  180.         pop     edi
  181.         mov     ebp, [esi-8]    ; dest_length
  182.         add     ebp, edi        ; ebp = destination limit
  183.         lodsd
  184. ; rd->code_ = eax
  185.         mov     [.code_], eax
  186.         or      [.range], -1
  187. .main_loop:
  188.         cmp     edi, ebp
  189.         jae     .main_loop_done
  190.         mov     edx, edi
  191.         and     edx, .posStateMask
  192.         mov     eax, ebx
  193.         shl     eax, .kNumPosBitsMax+2
  194.         lea     eax, [.IsMatch*4 + eax + edx*4]
  195.         add     eax, [.p]
  196.         call    .RangeDecoderBitDecode
  197.         jc      .1
  198.         movzx   eax, [.previousByte]
  199. if .literalPosMask
  200.         mov     ah, dl
  201.         and     ah, .literalPosMask
  202. end if
  203.         shr     eax, 8-.lc
  204.         imul    eax, .LZMA_LIT_SIZE*4
  205.         add     eax, .Literal*4
  206.         add     eax, [.p]
  207.         cmp     ebx, .kNumLitStates
  208.         jb      .literal
  209.         xor     edx, edx
  210.         sub     edx, [.rep0]
  211.         mov     dl, [edi + edx]
  212.         call    .LzmaLiteralDecodeMatch
  213.         jmp     @f
  214. .literal:
  215.         call    .LzmaLiteralDecode
  216. @@:
  217.         mov     [.previousByte], al
  218.         stosb
  219.         mov     al, bl
  220.         cmp     bl, 4
  221.         jb      @f
  222.         mov     al, 3
  223.         cmp     bl, 10
  224.         jb      @f
  225.         mov     al, 6
  226. @@:     sub     bl, al
  227.         jmp     .main_loop
  228. .1:
  229.         lea     eax, [.IsRep*4 + ebx*4]
  230.         add     eax, [.p]
  231.         call    .RangeDecoderBitDecode
  232.         jnc     .10
  233.         lea     eax, [.IsRepG0*4 + ebx*4]
  234.         add     eax, [.p]
  235.         call    .RangeDecoderBitDecode
  236.         jc      .111
  237.         mov     eax, ebx
  238.         shl     eax, .kNumPosBitsMax+2
  239.         lea     eax, [.IsRep0Long*4 + eax + edx*4]
  240.         add     eax, [.p]
  241.         call    .RangeDecoderBitDecode
  242.         jc      .1101
  243.         cmp     bl, 7
  244.         setae   bl
  245.         lea     ebx, [9 + ebx + ebx]
  246.         xor     edx, edx
  247.         sub     edx, [.rep0]
  248.         mov     al, [edi + edx]
  249.         stosb
  250.         mov     [.previousByte], al
  251.         jmp     .main_loop
  252. .111:
  253.         lea     eax, [.IsRepG1*4 + ebx*4]
  254.         add     eax, [.p]
  255.         call    .RangeDecoderBitDecode
  256.         mov     eax, [.rep1]
  257.         jnc     .l3
  258. .l1:
  259.         lea     eax, [.IsRepG2*4 + ebx*4]
  260.         add     eax, [.p]
  261.         call    .RangeDecoderBitDecode
  262.         mov     eax, [.rep2]
  263.         jnc     .l2
  264.         xchg    [.rep3], eax
  265. .l2:
  266.         push    [.rep1]
  267.         pop     [.rep2]
  268. .l3:
  269.         xchg    eax, [.rep0]
  270.         mov     [.rep1], eax
  271. .1101:
  272.         mov     eax, .RepLencoder*4
  273.         add     eax, [.p]
  274.         call    .LzmaLenDecode
  275.         cmp     bl, 7
  276.         setc    bl
  277.         adc     bl, bl
  278.         xor     bl, 3
  279.         add     bl, 8
  280.         jmp     .repmovsb
  281. .10:
  282.         mov     eax, [.rep0]
  283.         xchg    eax, [.rep1]
  284.         xchg    eax, [.rep2]
  285.         xchg    eax, [.rep3]
  286.         cmp     bl, 7
  287.         setc    bl
  288.         adc     bl, bl
  289.         xor     bl, 3
  290.         add     bl, 7
  291.         mov     eax, .Lencoder*4
  292.         add     eax, [.p]
  293.         call    .LzmaLenDecode
  294.         mov     eax, .kNumLenToPosStates-1
  295.         cmp     eax, ecx
  296.         jb      @f
  297.         mov     eax, ecx
  298. @@:
  299.         push    ecx
  300.         mov     ecx, .kNumPosSlotBits
  301.         shl     eax, cl
  302.         shl     eax, 2
  303.         add     eax, .PosSlot*4
  304.         add     eax, [.p]
  305.         call    .RangeDecoderBitTreeDecode
  306.         mov     [.rep0], ecx
  307.         cmp     ecx, .kStartPosModelIndex
  308.         jb      .l6
  309.         push    ecx
  310.         mov     eax, ecx
  311.         and     eax, 1
  312.         shr     ecx, 1
  313.         or      eax, 2
  314.         dec     ecx
  315.         shl     eax, cl
  316.         mov     [.rep0], eax
  317.         pop     edx
  318.         cmp     edx, .kEndPosModelIndex
  319.         jae     .l5
  320.         sub     eax, edx
  321.         shl     eax, 2
  322.         add     eax, (.SpecPos - 1)*4
  323.         add     eax, [.p]
  324.         call    .RangeDecoderReverseBitTreeDecode
  325.         add     [.rep0], ecx
  326.         jmp     .l6
  327. .l5:
  328.         sub     ecx, .kNumAlignBits
  329.         call    .RangeDecoderDecodeDirectBits
  330.         mov     ecx, .kNumAlignBits
  331.         shl     eax, cl
  332.         add     [.rep0], eax
  333.         mov     eax, .Align_*4
  334.         add     eax, [.p]
  335.         call    .RangeDecoderReverseBitTreeDecode
  336.         add     [.rep0], ecx
  337. .l6:
  338.         pop     ecx
  339.         inc     [.rep0]
  340.         jz      .main_loop_done
  341. .repmovsb:
  342.         add     ecx, .kMatchMinLen
  343.         push    esi
  344.         mov     esi, edi
  345.         sub     esi, [.rep0]
  346.         rep     movsb
  347.         pop     esi
  348.         mov     al, [edi-1]
  349.         mov     [.previousByte], al
  350.         jmp     .main_loop
  351. .main_loop_done:
  352.         ret
  353.  
  354. .RangeDecoderBitDecode:
  355. ; in: eax->prob
  356. ; out: CF=bit; destroys eax
  357.         push    edx
  358.         mov     edx, [.range]
  359.         shr     edx, .kNumBitModelTotalBits
  360.         imul    edx, [eax]
  361.         cmp     [.code_], edx
  362.         jae     .ae
  363.         mov     [.range], edx
  364.         mov     edx, .kBitModelTotal
  365.         sub     edx, [eax]
  366.         shr     edx, .kNumMoveBits
  367.         add     [eax], edx
  368.         clc
  369. .n:
  370.         lahf
  371.         cmp     [.range], .kTopValue
  372.         jae     @f
  373.         shl     [.range], 8
  374.         shl     [.code_], 8
  375.         lodsb
  376.         mov     byte [.code_], al
  377. @@:
  378.         sahf
  379.         pop     edx
  380.         ret
  381. .ae:
  382.         sub     [.range], edx
  383.         sub     [.code_], edx
  384.         mov     edx, [eax]
  385.         shr     edx, .kNumMoveBits
  386.         sub     [eax], edx
  387.         stc
  388.         jmp     .n
  389.  
  390. .RangeDecoderDecodeDirectBits:
  391. ; in: ecx=numTotalBits
  392. ; out: eax=result; destroys edx
  393.         xor     eax, eax
  394. .l:
  395.         shr     [.range], 1
  396.         shl     eax, 1
  397.         mov     edx, [.code_]
  398.         sub     edx, [.range]
  399.         jb      @f
  400.         mov     [.code_], edx
  401.         or      eax, 1
  402. @@:
  403.         cmp     [.range], .kTopValue
  404.         jae     @f
  405.         shl     [.range], 8
  406.         shl     [.code_], 8
  407.         push    eax
  408.         lodsb
  409.         mov     byte [.code_], al
  410.         pop     eax
  411. @@:
  412.         loop    .l
  413.         ret
  414.  
  415. .LzmaLiteralDecode:
  416. ; in: eax->probs
  417. ; out: al=byte; destroys edx
  418.         push    ecx
  419.         mov     ecx, 1
  420. @@:
  421.         push    eax
  422.         lea     eax, [eax+ecx*4]
  423.         call    .RangeDecoderBitDecode
  424.         pop     eax
  425.         adc     cl, cl
  426.         jnc     @b
  427. .LzmaLiteralDecode.ret:
  428.         mov     al, cl
  429.         pop     ecx
  430.         ret
  431. .LzmaLiteralDecodeMatch:
  432. ; in: eax->probs, dl=matchByte
  433. ; out: al=byte; destroys edx
  434.         push    ecx
  435.         mov     ecx, 1
  436. .LzmaLiteralDecodeMatch.1:
  437.         add     dl, dl
  438.         setc    ch
  439.         push    eax
  440.         lea     eax, [eax+ecx*4+0x100*4]
  441.         call    .RangeDecoderBitDecode
  442.         pop     eax
  443.         adc     cl, cl
  444.         jc      .LzmaLiteralDecode.ret
  445.         xor     ch, cl
  446.         test    ch, 1
  447.         mov     ch, 0
  448.         jnz     @b
  449.         jmp     .LzmaLiteralDecodeMatch.1
  450.  
  451. .LzmaLenDecode:
  452. ; in: eax->prob, edx=posState
  453. ; out: ecx=len
  454.         push    eax
  455.         add     eax, .LenChoice*4
  456.         call    .RangeDecoderBitDecode
  457.         pop     eax
  458.         jnc     .0
  459.         push    eax
  460.         add     eax, .LenChoice2*4
  461.         call    .RangeDecoderBitDecode
  462.         pop     eax
  463.         jc      @f
  464.         mov     ecx, .kLenNumMidBits
  465.         shl     edx, cl
  466.         lea     eax, [eax + .LenMid*4 + edx*4]
  467.         call    .RangeDecoderBitTreeDecode
  468.         add     ecx, .kLenNumLowSymbols
  469.         ret
  470. @@:
  471.         add     eax, .LenHigh*4
  472.         mov     ecx, .kLenNumHighBits
  473.         call    .RangeDecoderBitTreeDecode
  474.         add     ecx, .kLenNumLowSymbols + .kLenNumMidSymbols
  475.         ret
  476. .0:
  477.         mov     ecx, .kLenNumLowBits
  478.         shl     edx, cl
  479.         lea     eax, [eax + .LenLow*4 + edx*4]
  480. .RangeDecoderBitTreeDecode:
  481. ; in: eax->probs,ecx=numLevels
  482. ; out: ecx=length; destroys edx
  483.         push    ebx
  484.         mov     edx, 1
  485.         mov     ebx, edx
  486. @@:
  487.         push    eax
  488.         lea     eax, [eax+edx*4]
  489.         call    .RangeDecoderBitDecode
  490.         pop     eax
  491.         adc     dl, dl
  492.         add     bl, bl
  493.         loop    @b
  494.         sub     dl, bl
  495.         pop     ebx
  496.         mov     ecx, edx
  497.         ret
  498. .RangeDecoderReverseBitTreeDecode:
  499. ; in: eax->probs,ecx=numLevels
  500. ; out: ecx=length; destroys edx
  501.         push    ebx ecx
  502.         mov     edx, 1
  503.         xor     ebx, ebx
  504. @@:
  505.         push    eax
  506.         lea     eax, [eax+edx*4]
  507.         call    .RangeDecoderBitDecode
  508.         lahf
  509.         adc     edx, edx
  510.         sahf
  511.         rcr     ebx, 1
  512.         pop     eax
  513.         loop    @b
  514.         pop     ecx
  515.         rol     ebx, cl
  516.         mov     ecx, ebx
  517.         pop     ebx
  518.         ret
  519.  
  520. uglobal
  521. align 4
  522. ;unpack.p       rd      unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
  523. unpack.p        dd      ?
  524. unpack.code_    dd      ?
  525. unpack.range    dd      ?
  526. unpack.rep0     dd      ?
  527. unpack.rep1     dd      ?
  528. unpack.rep2     dd      ?
  529. unpack.rep3     dd      ?
  530. unpack.previousByte db  ?
  531. endg
  532.