Subversion Repositories Kolibri OS

Rev

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

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