Subversion Repositories Kolibri OS

Rev

Rev 425 | Rev 514 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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