Subversion Repositories Kolibri OS

Rev

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

  1. ; Branch filters for 7-Zip archives: BCJ and BCJ2.
  2. ; Ported from C++ sources of 7-Zip (c) Igor Pavlov.
  3. virtual at 0
  4. bcj_decoder:
  5. .outStream      rb      streamInfo.size
  6. .inStream       dd      ?
  7. .inPtr          dd      ?
  8. .inSize         dd      ?
  9. .nowPos         dd      ?               ; offset in stream
  10. .prevPos        dd      ?               ; pointer in buffer
  11. .prevMask       db      ?
  12. .numRest        db      ?
  13.                 rw      1
  14. .dwordRest      dd      ?
  15. .tempSize       dd      ?
  16. .tempDword      dd      ?
  17. .size = $
  18. end virtual
  19.  
  20. bcj_get_buf_size:
  21.         mov     eax, bcj_decoder.size
  22.         mov     edx, 0x4000
  23.         ret
  24.  
  25. bcj_init_decoder:
  26.         mov     [ebp+streamInfo.fillBuf], bcj_fillBuf
  27.         xor     edx, edx
  28.         mov     [ebp+bcj_decoder.inPtr], edx
  29.         mov     [ebp+bcj_decoder.inSize], edx
  30.         mov     [ebp+bcj_decoder.prevPos], edx
  31.         mov     [ebp+bcj_decoder.nowPos], edx
  32.         mov     [ebp+bcj_decoder.numRest], dl
  33.         ret
  34.  
  35. bcj_fillBuf:
  36.         add     [eax+bcj_decoder.nowPos], ecx
  37.         mov     ebp, ecx        ; save output size
  38.         mov     esi, [eax+bcj_decoder.inPtr]
  39.         mov     ebx, [eax+bcj_decoder.inStream]
  40.         mov     ecx, [eax+bcj_decoder.inSize]
  41.         add     esi, [ebx+streamInfo.bufPtr]
  42.         mov     ebx, eax
  43.         cmp     [eax+bcj_decoder.prevPos], 0
  44.         jz      @f
  45.         add     [eax+bcj_decoder.prevPos], edi
  46. @@:
  47.         cmp     [ebx+bcj_decoder.numRest], 0
  48.         jz      .mainloop
  49.         sub     ebp, 1
  50.         js      .mainloopdone
  51.         dec     [ebx+bcj_decoder.numRest]
  52.         mov     eax, [ebx+bcj_decoder.dwordRest]
  53.         stosb
  54.         shr     eax, 8
  55.         mov     [ebx+bcj_decoder.dwordRest], eax
  56.         jmp     @b
  57. .mainloop:
  58.         sub     ebp, 1
  59.         js      .mainloopdone
  60.         sub     ecx, 1
  61.         js      .refill1
  62. .filled1:
  63.         lodsb
  64. .filled2:
  65.         stosb
  66.         cmp     al, 0xE8
  67.         jz      .filter
  68.         cmp     al, 0xE9
  69.         jnz     .mainloop
  70. .filter:
  71.         and     [ebx+bcj_decoder.tempSize], 0
  72.         sub     ecx, 4
  73.         jb      .nopos
  74.         js      .nopos2
  75.         lodsd
  76.         push    eax
  77. .posok:
  78.         xor     edx, edx
  79.         mov     eax, edi
  80.         sub     eax, [ebx+bcj_decoder.prevPos]
  81.         cmp     eax, 5
  82.         ja      .maskok
  83.         movzx   edx, [ebx+bcj_decoder.prevMask]
  84. @@:
  85.         and     edx, 0x77
  86.         add     edx, edx
  87.         sub     eax, 1
  88.         jnz     @b
  89. .maskok:
  90.         mov     [ebx+bcj_decoder.prevMask], dl
  91.         mov     [ebx+bcj_decoder.prevPos], edi
  92.         mov     al, [esp+3]
  93.         add     al, 1
  94.         cmp     al, 2
  95.         jae     .miss
  96.         cmp     dl, 0x20
  97.         jae     .miss2
  98.         lea     eax, [edx-1]
  99.         test    eax, edx
  100.         jnz     .miss2
  101.         pop     eax
  102.         shr     edx, 1
  103.         push    ecx
  104.         mov     cl, [bcj_kMaskToBitNumber+edx]
  105. iglobal
  106. bcj_kMaskToBitNumber db 24,16,8,8,0,0,0,0
  107. endg
  108. @@:
  109.         sub     eax, [ebx+bcj_decoder.nowPos]
  110.         add     eax, [ebx+streamInfo.bufDataLen]
  111.         sub     eax, edi
  112.         sub     eax, 4
  113.         add     eax, [ebx+streamInfo.bufPtr]
  114.         cmp     cl, 24
  115.         jz      @f
  116.         push    eax
  117.         shr     eax, cl
  118.         add     al, 1
  119.         cmp     al, 2
  120.         pop     eax
  121.         jae     @f
  122.         mov     edx, 0x100
  123.         shl     edx, cl
  124.         sub     edx, 1
  125.         xor     eax, edx
  126.         jmp     @b
  127. @@:
  128.         pop     ecx
  129.         shl     eax, 7
  130.         sar     eax, 7
  131.         sub     ebp, 4
  132.         jb      .finalize_dword
  133.         stosd
  134.         jmp     .mainloop
  135. .miss2:
  136.         or      [ebx+bcj_decoder.prevMask], 10h
  137. .miss:
  138.         or      [ebx+bcj_decoder.prevMask], 1
  139.         cmp     [ebx+bcj_decoder.tempSize], 0
  140.         jz      @f
  141.         lea     esi, [ebx+bcj_decoder.tempDword]
  142.         pop     dword [esi]
  143.         mov     ecx, [ebx+bcj_decoder.tempSize]
  144.         jmp     .mainloop
  145. @@:
  146.         pop     eax
  147.         sub     esi, 4
  148.         add     ecx, 4
  149.         jmp     .mainloop
  150. .finalize_dword:
  151.         add     ebp, 4
  152.         mov     [ebx+bcj_decoder.numRest], 4
  153. @@:
  154.         dec     ebp
  155.         js      .save_dword
  156.         stosb
  157.         dec     [ebx+bcj_decoder.numRest]
  158.         shr     eax, 8
  159.         jmp     @b
  160. .save_dword:
  161.         mov     [ebx+bcj_decoder.dwordRest], eax
  162. .mainloopdone:
  163.         mov     eax, [ebx+bcj_decoder.prevPos]
  164.         test    eax, eax
  165.         jz      .noprev
  166.         sub     eax, edi
  167.         mov     [ebx+bcj_decoder.prevPos], eax
  168. .noprev:
  169.         mov     eax, [ebx+bcj_decoder.inStream]
  170.         sub     esi, [eax+streamInfo.bufPtr]
  171.         mov     [ebx+bcj_decoder.inPtr], esi
  172.         mov     [ebx+bcj_decoder.inSize], ecx
  173.         popad
  174.         ret
  175.  
  176. .refill1:
  177.         cmp     ecx, -1
  178.         jz      .refill0
  179.         lodsb
  180.         cmp     ecx, -4
  181.         jnz     @f
  182.         mov     ecx, [ebx+bcj_decoder.inStream]
  183.         mov     esi, [ecx+streamInfo.bufPtr]
  184.         mov     ecx, [ecx+streamInfo.bufDataLen]
  185. @@:
  186.         jmp     .filled2
  187. .refill0:
  188.         mov     eax, [ebx+bcj_decoder.inStream]
  189.         call    fillBuf
  190.         mov     esi, [eax+streamInfo.bufPtr]
  191.         mov     ecx, [eax+streamInfo.bufDataLen]
  192.         sub     ecx, 1
  193.         js      return.err
  194.         jmp     .filled1
  195.  
  196. .nopos:
  197.         mov     eax, [ebx+bcj_decoder.inStream]
  198.         cmp     dword [eax+streamInfo.fullSize+4], 0
  199.         jnz     .hasdata
  200.         push    ecx
  201.         add     ecx, dword [eax+streamInfo.fullSize]
  202.         pop     ecx
  203.         jc      .hasdata
  204.         add     ecx, 4
  205.         jmp     .mainloop
  206. .hasdata:
  207.         mov     [ebx+bcj_decoder.tempSize], ecx
  208.         push    0
  209.         push    edi
  210.         lea     edi, [esp+4]
  211.         add     ecx, 4
  212.         rep     movsb
  213.         sub     esi, ebx
  214.         sub     esi, 1
  215.         cmp     esi, bcj_decoder.tempDword+4
  216.         jbe     @f
  217.         call    fillBuf
  218. @@:
  219.         mov     esi, [eax+streamInfo.bufPtr]
  220.         mov     ecx, [ebx+bcj_decoder.tempSize]
  221.         neg     ecx
  222.         rep     movsb
  223.         pop     edi
  224.         mov     ecx, [eax+streamInfo.bufDataLen]
  225.         add     ecx, [ebx+bcj_decoder.tempSize]
  226.         cmp     [ebx+bcj_decoder.tempSize], -4
  227.         jnz     .posok
  228.         and     [ebx+bcj_decoder.tempSize], 0
  229.         jmp     .posok
  230. .nopos2:
  231.         mov     eax, [ebx+bcj_decoder.inStream]
  232.         add     ecx, 4
  233.         jmp     .hasdata
  234.  
  235. virtual at 0
  236. bcj2_decoder:
  237. .outStream      rb      streamInfo.size
  238. .mainInStream   dd      ?
  239. .callStream     dd      ?
  240. .jumpStream     dd      ?
  241. .rangeDecoder   dd      ?
  242. .dwordRest      dd      ?
  243. .prevByte       db      ?
  244. .numRest        db      ?
  245. .bInited        db      ?
  246.                 rb      1
  247. .inPtr          dd      ?
  248. .inSize         dd      ?
  249. .callPtr        dd      ?
  250. .jumpPtr        dd      ?
  251. .callSize       dd      ?
  252. .jumpSize       dd      ?
  253. .rangeDecPtr    dd      ?
  254. .rangeDecSize   dd      ?
  255. .nowPos         dd      ?
  256. .range          dd      ?
  257. .code           dd      ?
  258. .statusE9Decoder dd     ?
  259. .statusJccDecoder dd    ?
  260. .statusE8Decoder rd     256
  261. .size = $
  262. end virtual
  263.  
  264. bcj2_get_buf_size:
  265.         mov     eax, bcj2_decoder.size
  266.         mov     edx, 0x4000
  267.         ret
  268.  
  269. bcj2_init_decoder:
  270.         mov     [ebp+streamInfo.fillBuf], bcj2_fillBuf
  271.         mov     eax, lzma_decoder.kBitModelTotal/2
  272.         mov     ecx, 256+1+1
  273.         lea     edi, [ebp+bcj2_decoder.statusE9Decoder]
  274.         rep     stosd
  275.         mov     dword [ebp+bcj2_decoder.prevByte], ecx
  276.         mov     [ebp+bcj2_decoder.inSize], ecx
  277.         mov     [ebp+bcj2_decoder.callSize], ecx
  278.         mov     [ebp+bcj2_decoder.jumpSize], ecx
  279.         mov     [ebp+bcj2_decoder.rangeDecSize], ecx
  280.         mov     [ebp+bcj2_decoder.nowPos], ecx
  281.         ret
  282.  
  283. bcj2_fillBuf.init:
  284.         mov     eax, [eax+bcj2_decoder.rangeDecoder]
  285.         call    fillBuf
  286.         mov     edx, [eax+streamInfo.bufDataLen]
  287.         sub     edx, 5
  288.         jb      return.err
  289.         mov     [ebp+bcj2_decoder.rangeDecSize], edx
  290.         mov     edx, [eax+streamInfo.bufPtr]
  291.         add     edx, 5
  292.         mov     [ebp+bcj2_decoder.rangeDecPtr], edx
  293.         mov     edx, [edx-4]
  294.         bswap   edx
  295.         mov     [ebp+bcj2_decoder.code], edx
  296.         or      [ebp+bcj2_decoder.range], -1
  297.         mov     [ebp+bcj2_decoder.bInited], 1
  298.         mov     eax, ebp
  299.         jmp     bcj2_fillBuf.inited
  300.  
  301. bcj2_fillBuf:
  302.         mov     ebp, eax
  303.         cmp     [eax+bcj2_decoder.bInited], 0
  304.         jz      .init
  305. .inited:
  306.         add     [eax+bcj2_decoder.nowPos], ecx
  307.         mov     esi, [eax+bcj2_decoder.inPtr]
  308. @@:
  309.         cmp     [ebp+bcj2_decoder.numRest], 0
  310.         jz      .mainloop
  311.         sub     ecx, 1
  312.         js      .mainloopdone
  313.         dec     [ebp+bcj2_decoder.numRest]
  314.         mov     eax, [ebp+bcj2_decoder.dwordRest]
  315.         stosb
  316.         mov     [ebp+bcj2_decoder.prevByte], al
  317.         shr     eax, 8
  318.         mov     [ebp+bcj2_decoder.dwordRest], eax
  319.         jmp     @b
  320. .mainloop:
  321.         sub     ecx, 1
  322.         js      .mainloopdone
  323.         sub     [ebp+bcj2_decoder.inSize], 1
  324.         js      .refill1
  325. .filled1:
  326.         lodsb
  327.         stosb
  328.         cmp     al, 0xE8
  329.         jz      .e8
  330.         cmp     al, 0xE9
  331.         jz      .e9
  332.         cmp     [ebp+bcj2_decoder.prevByte], 0xF
  333.         mov     [ebp+bcj2_decoder.prevByte], al
  334.         jnz     .mainloop
  335.         and     al, 0xF0
  336.         cmp     al, 0x80
  337.         jnz     .mainloop
  338. .jcc:
  339.         lea     eax, [ebp+bcj2_decoder.statusJccDecoder]
  340.         call    .RangeDecoderBitDecode
  341.         jnc     .mainloop
  342.         jmp     .getptrj
  343. .e8:
  344.         movzx   eax, al
  345.         xchg    al, [ebp+bcj2_decoder.prevByte]
  346.         lea     eax, [ebp+bcj2_decoder.statusE8Decoder+eax*4]
  347.         call    .RangeDecoderBitDecode
  348.         jnc     .mainloop
  349.         lea     eax, [ebp+bcj2_decoder.callPtr]
  350.         jmp     .getptr
  351. .e9:
  352.         mov     [ebp+bcj2_decoder.prevByte], al
  353.         lea     eax, [ebp+bcj2_decoder.statusE9Decoder]
  354.         call    .RangeDecoderBitDecode
  355.         jnc     .mainloop
  356. .getptrj:
  357.         lea     eax, [ebp+bcj2_decoder.jumpPtr]
  358. .getptr:
  359.         sub     dword [eax+8], 4
  360.         js      .refill2
  361. .filled2:
  362.         add     dword [eax], 4
  363.         mov     eax, [eax]
  364.         mov     eax, [eax-4]
  365.         bswap   eax
  366.         sub     eax, [ebp+bcj2_decoder.nowPos]
  367.         add     eax, [ebp+streamInfo.bufDataLen]
  368.         sub     eax, edi
  369.         sub     eax, 4
  370.         add     eax, [ebp+streamInfo.bufPtr]
  371.         sub     ecx, 4
  372.         jb      .finalize_dword
  373.         stosd
  374.         shr     eax, 24
  375.         mov     [ebp+bcj2_decoder.prevByte], al
  376.         jmp     .mainloop
  377. .finalize_dword:
  378.         add     ecx, 4
  379.         mov     [ebp+bcj2_decoder.numRest], 4
  380. @@:
  381.         dec     ecx
  382.         js      .save_dword
  383.         stosb
  384.         dec     [ebp+bcj2_decoder.numRest]
  385.         shr     eax, 8
  386.         jmp     @b
  387. .save_dword:
  388.         mov     [ebp+bcj2_decoder.dwordRest], eax
  389. .mainloopdone:
  390.         mov     [ebp+bcj2_decoder.inPtr], esi
  391.         popad
  392.         ret
  393.  
  394. .refill1:
  395.         mov     eax, [ebp+bcj2_decoder.mainInStream]
  396.         call    fillBuf
  397.         mov     edx, [eax+streamInfo.bufDataLen]
  398.         dec     edx
  399.         js      return.err
  400.         mov     [ebp+bcj2_decoder.inSize], edx
  401.         mov     esi, [eax+streamInfo.bufPtr]
  402.         jmp     .filled1
  403.  
  404. .refill2:
  405.         push    eax
  406.         mov     eax, [eax-bcj2_decoder.callPtr+bcj2_decoder.callStream]
  407.         call    fillBuf
  408.         mov     edx, [eax+streamInfo.bufDataLen]
  409.         sub     edx, 4
  410.         js      return.err
  411.         push    [eax+streamInfo.bufPtr]
  412.         mov     eax, [esp+4]
  413.         pop     dword [eax]
  414.         pop     eax
  415.         mov     [eax+8], edx
  416.         jmp     .filled2
  417.  
  418. .refill3:
  419.         push    eax
  420.         mov     eax, [ebp+bcj2_decoder.rangeDecoder]
  421.         call    fillBuf
  422.         mov     edx, [eax+streamInfo.bufDataLen]
  423.         dec     edx
  424.         js      return.err
  425.         mov     [ebp+bcj2_decoder.rangeDecSize], edx
  426.         mov     edx, [eax+streamInfo.bufPtr]
  427.         mov     [ebp+bcj2_decoder.rangeDecPtr], edx
  428.         pop     eax
  429.         jmp     .filled3
  430.  
  431. .RangeDecoderBitDecode:
  432. ; in: eax->prob
  433. ; out: CF=bit; destroys eax,edx
  434.         mov     edx, [ebp+bcj2_decoder.range]
  435.         shr     edx, lzma_decoder.kNumBitModelTotalBits
  436.         imul    edx, [eax]
  437.         cmp     [ebp+bcj2_decoder.code], edx
  438.         jae     .ae
  439.         mov     [ebp+bcj2_decoder.range], edx
  440.         mov     edx, lzma_decoder.kBitModelTotal
  441.         sub     edx, [eax]
  442.         shr     edx, lzma_decoder.kNumMoveBits
  443.         add     [eax], edx
  444.         clc
  445. .n:
  446.         lahf
  447.         cmp     [ebp+bcj2_decoder.range], lzma_decoder.kTopValue
  448.         jae     @f
  449.         shl     [ebp+bcj2_decoder.range], 8
  450.         shl     [ebp+bcj2_decoder.code], 8
  451.         dec     [ebp+bcj2_decoder.rangeDecSize]
  452.         js      .refill3
  453. .filled3:
  454.         mov     edx, [ebp+bcj2_decoder.rangeDecPtr]
  455.         mov     al, [edx]
  456.         add     edx, 1
  457.         mov     [ebp+bcj2_decoder.rangeDecPtr], edx
  458.         mov     byte [ebp+bcj2_decoder.code], al
  459. @@:
  460.         sahf
  461.         ret
  462. .ae:
  463.         sub     [ebp+bcj2_decoder.range], edx
  464.         sub     [ebp+bcj2_decoder.code], edx
  465.         mov     edx, [eax]
  466.         shr     edx, lzma_decoder.kNumMoveBits
  467.         sub     [eax], edx
  468.         stc
  469.         jmp     .n
  470.