Subversion Repositories Kolibri OS

Rev

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