Subversion Repositories Kolibri OS

Rev

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

  1. ; @RCHER parser and filter routines
  2. ; Written in pure assembler by Ivushkin Andrey aka Willow
  3.  
  4.   fhs_local   equ 0x04034b50
  5.   fhs_central equ 0x02014b50
  6.   fhs_end     equ 0x06054b50
  7.   fhs_enc     equ 0x08074b50
  8.  
  9. SkipASCIIZ:
  10.     xor  eax,eax
  11.     mov  ecx,255
  12.     mov  edi,esi
  13.     repne scasb
  14.     mov  esi,edi
  15.     ret
  16.  
  17. PrintFilename:
  18.     pusha
  19.     mov  esi,edx
  20.     mov  edi,os_work
  21.     mov  edx,edi
  22.     rep  movsb
  23.     mov  dword[edi],0x00a0d
  24.     call DebugPrint
  25. ;    mcall 10
  26. ;    mcall 2
  27.     popa
  28.     ret
  29.  
  30.  
  31. ; Parse routines:
  32. ;   out: edx= 0 if all ok, 1 - central dir, 2-EOD
  33. ;             50 - encrypted
  34. ;             51 - not deflated
  35. ;             52 - invalid format
  36. ;             53 - dir skipped
  37. ;             1 - encrypted
  38.  
  39. ; ****************************************************
  40. ZipParse:
  41.  
  42.     call ResetFile
  43.   .nxt:
  44.     call ZipCrawl
  45.  
  46.     cmp  edx,3
  47.     je  .ex
  48.     cmp  edx,1
  49.     je   .skipinc
  50. if  IGNORE_DIRS eq 1
  51.     cmp  edx,53
  52.     jne  .skipinc
  53. end if
  54.     inc  [file_count]
  55.   .skipinc:
  56.     cmp  edx,52
  57.     je   .er1
  58.     cmp  edx,50
  59.     jne   .seek
  60.   .er1:
  61.     Msg  edx
  62.     ret
  63.   .seek:
  64.     add  eax,ecx
  65.     mov  ebx,1
  66.     call FileSeek
  67.     jmp  .nxt
  68.   .ex:
  69.     Msg  2
  70.     mov  eax,[file_count]
  71.  if ~ SYS eq win
  72.     dpd  eax
  73.  else
  74.     pusha
  75.     call  int2str
  76.     mov   edx,os_work
  77.         call  DebugPrint
  78.         popa
  79.  end if
  80.     Newline
  81.     ret
  82.  
  83. ZipFindN:
  84. ; ecx - file #
  85.     Msg 33
  86.     cmp  ecx,[file_count]
  87.     jae  .err
  88.     push ecx
  89.     call ResetFile
  90.   .nxt:
  91.     call ZipCrawl
  92.     cmp  edx,51
  93.     je   .ok2
  94.   .noenc:
  95.     test edx,edx
  96.     jnz  .err
  97.   .ok2:
  98.     add  eax,ecx
  99.     cmp  dword[esp],0
  100.     jz   .ok
  101.     dec  dword[esp]
  102.     mov  ebx,1
  103.     call FileSeek
  104.     jmp  .nxt
  105.   .err:
  106.     mov  edx,4
  107.     jmp  .ex
  108.   .ok:
  109.     pop  ecx
  110.     sub  eax,[esi+18]
  111.     add  esi,eax
  112.     mov  edx,5
  113.   .ex:
  114.     push edx
  115.     Msg  edx
  116.     pop  edx
  117.     ret
  118.  
  119. ZipCrawl:
  120.     mov  edx,52
  121.     cmp  dword[esi],fhs_central
  122.     jne  .noc
  123.     mov  eax,46
  124.     movzx ecx,word[esi+28]
  125.     add  eax,ecx
  126.     movzx ecx,word[esi+30]
  127.     add  eax,ecx
  128.     movzx ecx,word[esi+32]
  129.     mov  edx,1
  130.     ret
  131.   .noc:
  132.     cmp  dword[esi],fhs_end
  133.     jne  .noe
  134.   .edx3:
  135.     Msg 3
  136.     mov  edx,3
  137.     ret
  138.   .noe:
  139.     cmp  dword[esi],fhs_local
  140.     je   .loc
  141.     cmp  dword[esi],fhs_enc
  142.     jne  .err
  143.     mov  eax,16
  144.     xor  ecx,ecx
  145.     mov  edx,1
  146.     ret
  147.   .loc:
  148.     push word[esi+6]
  149.     pop  [gpbf]
  150.     push dword[esi+14]
  151.     pop  [CRC_check]
  152.     push dword[esi+22]
  153.     pop  [unp_size]
  154.     movzx ecx,word[esi+26]
  155.     mov  eax,30
  156.     lea  edx,[esi+eax]
  157.     add  eax,ecx
  158. if  IGNORE_DIRS eq 1
  159.     cmp  byte[edx+ecx-1],'/'
  160.     je   .skipdp
  161. end if
  162.     call PrintFilename
  163.   .skipdp:
  164.     movzx ecx,word[esi+28]
  165.     add  eax,[esi+18]
  166.     test [gpbf],1
  167.     jz   .no_enc
  168.     or   [Flags],DECRYPT_MODE  ; encrypted
  169.     mov  edx,51
  170.     jmp  .err
  171.   .no_enc:
  172.     test word[esi+8],7
  173.     rep_err z,50
  174.   .ok:
  175.     xor  edx,edx
  176.   .err:
  177.     ret
  178.  
  179. ; ***********************************************
  180. GzipParse:
  181.     ID1ID2 equ 0x8b1f
  182.     FTEXT equ 1b
  183.     FHCRC equ 10b
  184.     FEXTRA equ 100b
  185.     FNAME equ 1000b
  186.     FCOMMENT equ 10000b
  187.     mov  eax,7
  188.     mov  ebx,2
  189.     call FileSeek
  190.     push dword[esi]
  191.     pop  [CRC_check]
  192.     push dword[esi+4]
  193.     pop  [unp_size]
  194.     call ResetFile
  195.     xor  edx,edx
  196.     cmp  word[esi],ID1ID2
  197.     rep_err e, 52, 15
  198.     cmp  byte[esi+2],8
  199.     rep_err e, 52, 50
  200.     mov  bl,[esi+3]  ; bl - FLG
  201.     add  esi,10 ; esi->extra
  202.     test bl,FEXTRA
  203.     jz   .noextr
  204.     movzx eax,word[esi]
  205.     lea  esi,[esi+eax+2] ; esi->FNAME
  206.   .noextr:
  207.     test bl,FNAME
  208.     jz   .nofname
  209.     mov  edx,esi
  210.     call DebugPrint
  211.     call SkipASCIIZ
  212.     cmp  dword[esi-5],'.tar'
  213.     jne  .nofname
  214.     or   [Flags],TAR_MODE
  215.   .nofname:     ; esi->FCOMMENT
  216.     test bl,FCOMMENT
  217.     jz   .nocomm
  218.     call SkipASCIIZ
  219.   .nocomm:      ; esi->HCRC
  220.     test bl,FHCRC
  221.     jz   .noCRC16
  222.     add  esi,2
  223.   .noCRC16:
  224.     cmp  [unp_size],OUTBUF
  225.     jb   .sizeok2
  226.     Msg  16
  227.     mov  edx,15
  228.     ret
  229.   .sizeok2:
  230.     xor  edx,edx
  231.   .err:
  232.     ret
  233.  
  234. PngParse:
  235.     ID1 equ 0x474e5089
  236.     ID2 equ 0x0a1a0a0d
  237.     FDICT equ 100000b
  238.     InitIDAT equ 2
  239.     mov  [IDATcount],InitIDAT
  240.     call ResetFile
  241.     cmp  dword[esi],ID1
  242.     rep_err e, 52, 18
  243.     cmp  dword[esi+4],ID2
  244.     rep_err e, 52, 18
  245.     add  esi,8
  246.     cmp  dword[esi+4],'IHDR'
  247.     rep_err e,52, 18
  248.     or   [Flags],PNG_MODE
  249.     memcpy_esi PNG_info,13,8
  250.     mov  eax,[PNG_info.Width]
  251.     bswap eax
  252.     mov  [PNG_info.Width],eax
  253.     mov  eax,[PNG_info.Height]
  254.     bswap eax
  255.     mov  [PNG_info.Height],eax
  256.     add  esi,25
  257.     cmp  byte[esi-5],0
  258.     rep_err e,52,29
  259.   .nxt_sec:
  260.     lodsd
  261.     bswap eax ; eax - section size
  262.     push eax
  263.     lodsd
  264.     mov  edi,Png_ch
  265.     mov  ecx,(E_ch-Png_ch) / 4
  266.     repne scasd
  267.     pop  eax
  268.     mov  ebx,[esi-4]
  269.     mov  edx,os_work
  270.     mov  [edx],ebx
  271.     mov  dword[edx+4],0x0a0d
  272.   .dp:
  273.     sub  edi,Png_ch
  274.     shr  edi,2  ; edi- chunk #
  275.  if SHOW_PNG_SEC eq 1
  276.     call DebugPrint
  277.  end if
  278.     cmp  edi,1
  279.     jne  .noend
  280.     mov  edx,21
  281.     jmp  .err
  282.   .noend:
  283.     cmp  edi,2
  284.     jne  .noplte
  285.     memcpy_esi PNG_info.Palette,eax
  286.     jmp  .noidat
  287.    .noplte:
  288.     cmp  edi,3
  289.     jne  .noidat
  290.     mov  [IDATsize],eax
  291.     cmp  [IDATcount],InitIDAT
  292.     jne  .ex
  293.     mov  [bits],8
  294.   if RBLOCK eq 4
  295.     lodsd
  296.   else
  297.     lodsb
  298.   end if
  299.     call setcurb
  300.     rbits 0,16
  301.     test ah,FDICT
  302.     jz   .ex
  303.     rbits 0,32
  304.     add  [IDATcount],4
  305.     jmp  .ex
  306.    .noidat:
  307.     add  eax,4
  308.     mov  ebx,1
  309.     call FileSeek
  310.     jmp  .nxt_sec
  311.    .ex:
  312.     xor  edx,edx
  313.    .err:
  314.     ret
  315.  
  316. Png_ch:
  317.     dd 'IEND','PLTE','IDAT','????'
  318. E_ch:
  319.  
  320. ZipDecrypt:
  321.     push edi
  322.     mov  ecx,3
  323.     mov  edi,Dheader
  324.     rep  movsd
  325.     pop  edi
  326.     call QueryPwd
  327.     jecxz .ex
  328.     push esi
  329.     mov  [DKeys],  305419896
  330.     mov  [DKeys+4],591751049
  331.     mov  [DKeys+8],878082192
  332.     xor  eax,eax
  333.     mov  esi,Dpassword
  334.   .enc_init:
  335.     lodsb
  336.     call UKeys
  337.     loop .enc_init
  338.     mov  ecx,12
  339.     mov  esi,Dheader
  340.   .dec_header:
  341.     call decrypt_byte
  342.     xor  al,[esi]
  343.     call UKeys
  344.     mov  [esi],al
  345.     inc  esi
  346.     loop .dec_header
  347.     mov  eax,[CRC_check]
  348.     pop  esi
  349.   .ex:
  350.     ret
  351.  
  352. QueryPwd:
  353. ; out: ecx - passwd len
  354. if  SYS eq win
  355.     Msg 32
  356.     invoke ReadConsole,[cons_in],Dpassword,PASSW_LEN,cparam1,NULL
  357.     test eax,eax
  358.     jnz  .inp_ok
  359.     xor  ecx,ecx
  360.     jmp  .ex
  361.   .inp_ok:
  362.     mov  ecx,[cparam1]
  363.     cmp  ecx,PASSW_LEN
  364.     je   .ex
  365.     sub  ecx,2
  366. else
  367. end if
  368.   .ex:
  369.     ret
  370.  
  371. UKeys:
  372. ; in: al - char
  373.     pusha
  374.     mov  edi,134775813
  375.     mov  ebx,DKeys
  376.     mov  esi,os_work
  377.     mov  byte[esi],al
  378.     mov  ecx,1
  379.     push dword[ebx]
  380.     pop  [CRC32]
  381.     call UCRC
  382.     push [CRC32]
  383.     pop  dword[ebx]
  384.     mov  eax,[ebx]
  385.     and  eax,0xff
  386.     add  eax,[ebx+4]
  387.     mul  edi
  388.     inc  eax
  389.     mov  [ebx+4],eax
  390.     shr  eax,24
  391.     mov  byte[esi],al
  392.     push dword[ebx+8]
  393.     pop  [CRC32]
  394.     call UCRC
  395.     push [CRC32]
  396.     pop  dword[ebx+8]
  397.     popa
  398.     ret
  399.  
  400. decrypt_byte:
  401. ; out: al
  402.     push ebx edx
  403.     movzx ebx,word[DKeys+8]
  404.     or   ebx,2
  405.     mov  eax,ebx
  406.     xor  eax,1
  407.     mul  ebx
  408.     shr  eax,8
  409.     pop  edx ebx
  410.     ret
  411.  
  412. setcurb:
  413. ; in: eax
  414.     test [Flags],DECRYPT_MODE
  415.     jz   .noenc
  416.     push eax
  417.     call decrypt_byte
  418.     xor  al,byte[esp]
  419.     add  esp,4
  420.     call UKeys
  421.   .noenc:
  422.     mov  [cur_byte],eax
  423.     ret
  424.  
  425. TarParse:
  426.     call ResetFile
  427.   .nxt:
  428.     call TarCrawl
  429. ;    wait
  430.     cmp  edx,3
  431.     je   ZipParse.ex
  432. if  IGNORE_DIRS eq 1
  433.     cmp  edx,53
  434.     jne  .skipinc
  435. end if
  436.     inc  [file_count]
  437.   .skipinc:
  438.     add  eax,ecx
  439.     mov  ebx,1
  440.     call FileSeek
  441.     jmp  .nxt
  442.  
  443. TarFindN:
  444. ; in:  ecx - file number
  445. ; ecx - file #
  446.     Msg 33
  447.     cmp  ecx,[file_count]
  448.     jae  .err
  449.     push ecx
  450.     call ResetFile
  451.   .nxt:
  452.     call TarCrawl
  453. if  IGNORE_DIRS eq 1
  454.     cmp  edx,53
  455.     je  .seek
  456. end if
  457.     test edx,edx
  458.     jnz  .err
  459.     cmp  dword[esp],0
  460.     jz   .ok
  461.     dec  dword[esp]
  462.   .seek:
  463.     add  eax,ecx
  464.     mov  ebx,1
  465.     call FileSeek
  466.     jmp  .nxt
  467.   .err:
  468.     mov  edx,4
  469.     jmp  .ex
  470.   .ok:
  471.     pop  ecx
  472.     add  esi,eax
  473.     mov  edx,5
  474.   .ex:
  475.     Msg  edx
  476.     ret
  477.  
  478. TarCrawl:
  479.     cmp  byte[esi],0
  480.     jz   ZipCrawl.edx3
  481.     push esi
  482.     mov  ecx,11
  483.     add  esi,0x7c
  484.     call Octal_str
  485.     mov  esi,[esp]
  486.     mov  [outfile.size],eax
  487.     call SkipASCIIZ
  488. if  IGNORE_DIRS eq 1
  489.     cmp  byte[esi-2],'/'
  490.     je   .skipdp
  491. end if
  492.     mov  edx,[esp]
  493.     lea  ecx,[esi-1]
  494.     sub  ecx,edx
  495.     call PrintFilename
  496.   .skipdp:
  497.     mov  ecx,[outfile.size]
  498.     jecxz .zerolen
  499.     shr  ecx,9
  500.     inc  ecx
  501.     shl  ecx,9
  502.   .zerolen:
  503.     mov  eax,512
  504.     pop  esi
  505.     jmp  ZipCrawl.ok
  506.  
  507. Octal_str:
  508. ; in:  esi - ASCIIZ octal string
  509. ;      ecx - its length
  510. ; out: eax - value
  511.     push esi ebx ecx
  512.     xor  ebx,ebx
  513.     xor  eax,eax
  514.   .jec:
  515.     jecxz .zero
  516.     cmp  byte[esi+ecx-1],' '
  517.     jne  .lp
  518.     dec  ecx
  519.     jmp  .jec
  520.   .lp:
  521.     lodsb
  522.     shl  ebx,3
  523.     cmp  eax,' '
  524.     je   .space
  525.     lea  ebx,[ebx+eax-'0']
  526.   .space:
  527.     loop .lp
  528.     mov  eax,ebx
  529.   .zero:
  530.     pop  ecx ebx esi
  531.     ret
  532.  
  533. TRAILING_BUF equ 2048
  534. SfxParse:
  535.     call ResetFile
  536.     cmp  word[esi],'MZ'
  537.     rep_err e, 34
  538.     mov  eax,TRAILING_BUF
  539.     mov  ecx,eax
  540.     mov  ebx,2
  541.     call FileSeek
  542.     mov  edi,esi
  543.     mov  al,'P'
  544.   .lp:
  545.     repne scasb
  546.     cmp  dword[edi-1],fhs_end
  547.     je   .end_found
  548.     jecxz .err
  549.     jmp   .lp
  550.   .end_found:
  551.     dec   edi
  552.     mov   esi,edi
  553.     mov   eax,[edi+12]
  554.     neg   eax
  555.     mov   ebx,1
  556.     call  FileSeek
  557.     push  dword[esi+42]
  558.     pop   [arc_base]
  559.   .err:
  560.     ret
  561.  
  562. ; Created:  May 31, 2005
  563. FiltCall:
  564. dd PngFilter.nofilt,Filt_sub,Filt_up,Filt_av,Filt_paeth,PngFilter.nofilt
  565. PngFilter:
  566. ; esi - filtered uncompressed image data
  567. ; edi - destination
  568.     mov  cl,[PNG_info.Color_type]
  569.     mov  eax,1
  570.     cmp  cl,3
  571.     je   .palette
  572.     test cl,2
  573.     jz  .notriple
  574.     add  eax,2
  575.   .notriple:
  576.     test cl,4
  577.     jz   .calc_bpp
  578.     inc  eax
  579.   .calc_bpp:
  580.     mul  [PNG_info.Bit_depth]
  581.   .palette:
  582.     mov  ecx,eax   ; in bits
  583.     shr  eax,3     ; in bytes
  584.     test eax,eax
  585.     jnz  .noz
  586.     inc  eax
  587.   .noz:
  588.     mov  [png_bpp],eax
  589.     mov  eax,[PNG_info.Width]
  590.     mov  ebp,eax
  591.     imul ecx
  592.     shr  eax,3
  593.     test eax,eax
  594.     jnz  .noz2
  595.     inc  eax
  596.   .noz2:
  597.     mov  [sline_len],eax   ; scanline length
  598.     push edi
  599.     and  [Flags],not 1
  600.     mov  ecx,[PNG_info.Height]
  601.   .scanline:
  602. ;    Msg 9,1
  603.     push ecx
  604.     lodsb
  605.     movzx eax,al
  606.     cmp  eax,5
  607.     jb   .f_ok
  608.     mov  eax,5
  609.   .f_ok:
  610.     inc  dword[filters+eax*4]
  611.     jmp  dword[FiltCall+eax*4]
  612.   .nofilt:
  613.     mov  dl,[PNG_info.Color_type]
  614.     cmp  dl,3
  615.     jne  .nopalette
  616.     lodsb
  617.     mov  [cur_byte],eax
  618.     mov  [bits],8
  619.     mov  ecx,ebp
  620.   .pixel:
  621.     push ecx
  622.     movzx ecx,[PNG_info.Bit_depth]
  623.     call rb_png
  624.     push esi
  625.     lea  esi,[eax+eax*2]
  626.     add  esi,PNG_info.Palette
  627.     call PngStore
  628.     pop  esi
  629.     pop  ecx
  630.     loop .pixel
  631.     cmp  [bits],8
  632.     jne  .lp
  633.     dec  esi
  634.   .lp:
  635.     pop  ecx
  636.     loop .sl
  637.     jmp  .sl2
  638.   .sl:
  639. ;//
  640. MV equ 1
  641. ;    mov  eax,ecx
  642. ;    and  eax,1 shl MOVE_SLINE_LEV-1
  643. ;    jnz  .scanline
  644. ;stop
  645. if MV eq 0
  646.     push ecx
  647.     mov  ecx,edi
  648.     sub  ecx,esi
  649.     sub  [outp],esi
  650.     mov  edi,output
  651.     add  [outp],edi
  652.     rep  movsb
  653.     mov  esi,output
  654.     pop  ecx
  655.     pop  eax
  656.     push [outp]
  657. end if
  658. ;;//
  659.     jmp  .scanline
  660.   .sl2:
  661. ;//
  662. ;    call MoveScanline
  663.     sub  edi,[outp]
  664. ;//
  665. ;    sub  edi,[esp]
  666.     pop  eax
  667.     ret
  668.  
  669.   .nopalette:
  670.     test  dl,2
  671.     jz   .notriple1
  672.   .__:
  673.     mov  ecx,[PNG_info.Width]
  674.   .RGBcp:
  675.     call PngStore
  676.     add  esi,[png_bpp]
  677.     loop .RGBcp
  678.     jmp  .lp
  679.   .notriple1:
  680.     test dl,dl
  681.     jz  .gray
  682.     cmp  dl,4
  683.     jne .__
  684. ;    Msg 31
  685. ;    ud2
  686.   .gray:
  687. ;    stop
  688.     push ecx
  689.     mov  ecx,[PNG_info.Width]
  690.     mov  [bits],8
  691.     lodsb
  692.     mov  [cur_byte],eax
  693.   .gray2:
  694.     push ecx
  695.     movzx ecx,[PNG_info.Bit_depth]
  696.     push ecx
  697.     call rb_png
  698.     pop  ecx
  699.     cmp  ecx,8
  700.     jbe  .lo
  701.     add  esi,2
  702.     shr  eax,8
  703.     jmp  .stsb
  704.   .lo:
  705.     neg  ecx
  706.     add  ecx,8
  707.     shl  eax,cl
  708.   .stsb:
  709.     mov  ecx,3
  710.     rep  stosb
  711.     pop  ecx
  712.     loop .gray2
  713.     dec  esi
  714.     pop  ecx
  715.     jmp  .lp
  716.  
  717. Filt_sub:
  718. ;    dps  '-'
  719.     mov  ecx,[sline_len]
  720.     sub  ecx,[png_bpp]
  721.     push esi edi
  722.     mov  edi,esi
  723.     add  edi,[png_bpp]
  724.   .scan:    ; esi - previous, edi - current
  725.     lodsb
  726.     add  [edi],al
  727.     inc  edi
  728.     loop .scan
  729.  
  730.     pop  edi esi
  731. ;    dps  '-'
  732.     jmp  PngFilter.nofilt
  733.  
  734. Filt_up:
  735.     cmp  ecx,[PNG_info.Height]
  736.     je   PngFilter.nofilt
  737.     push esi edi
  738.     mov  ecx,[sline_len]
  739.     mov  edi,esi
  740.     sub  esi,ecx
  741.     dec  esi
  742.     jmp  Filt_sub.scan
  743.  
  744. Filt_av:
  745.     pusha
  746.     mov  ecx,[sline_len]
  747.     mov  ebp,[PNG_info.Height]
  748.     mov  edx,[png_bpp] ; edx-raw
  749.     neg  edx
  750.     mov  ebx,ecx
  751.     sub  ebx,[png_bpp]
  752.     mov  edi,esi
  753.     sub  esi,ecx
  754.     dec  esi           ; esi-prior
  755.   .lpavg:
  756.     xor  eax,eax
  757.     cmp  [esp+24h],ebp
  758.     je   .1stl
  759.     movzx eax,byte[esi]
  760.   .1stl:
  761.     cmp  ecx,ebx
  762.     ja   .leftbad
  763.     push ecx
  764.     movzx ecx,byte[edi+edx]
  765.     add  eax,ecx
  766.     pop  ecx
  767.   .leftbad:
  768.     shr  eax,1
  769.     add  [edi],al
  770.     inc  esi
  771.     inc  edi
  772.     loop .lpavg
  773.     popa
  774.     jmp  PngFilter.nofilt
  775.  
  776. Filt_paeth:
  777.     pusha
  778.     mov  ecx,[sline_len]
  779.     mov  edx,[png_bpp]
  780.     neg  edx
  781.     lea  ebp,[ecx+edx] ; left edge
  782.     mov  edi,esi
  783.     sub  esi,ecx
  784.     dec  esi
  785.   .lpaeth:
  786.     push ecx
  787.     movzx eax,byte[edi+edx]
  788.     movzx ebx,byte[esi]
  789.     movzx ecx,byte[esi+edx]
  790.     push eax
  791.     mov  eax,[esp+28h]
  792.     cmp  eax,[PNG_info.Height] ; 1st line
  793.     jne  .no1stlineok
  794.     xor  ebx,ebx
  795.     xor  ecx,ecx
  796.   .no1stlineok:
  797.     pop  eax
  798.     cmp  [esp],ebp     ; ecx
  799.     jbe  .leftok      ; x-bpp>=0
  800.     xor  eax,eax
  801.     xor  ecx,ecx
  802.   .leftok:
  803.     pusha   ; eax-28, ebx-16, ecx-24
  804.     lea  edx,[eax+ebx]
  805.     sub  edx,ecx        ; p=edx
  806.     sub  eax,edx        ; pa := abs(p - a)
  807.     jge  .eaxp
  808.     neg  eax
  809.   .eaxp:
  810.     sub  ebx,edx        ; pb := abs(p - b)
  811.     jge  .ebxp
  812.     neg  ebx
  813.   .ebxp:
  814.     sub  ecx,edx        ; pc := abs(p - c)
  815.     jge  .ecxp
  816.     neg  ecx
  817.   .ecxp:
  818.     cmp  eax,ebx
  819.     ja   .noa
  820.     cmp  eax,ecx
  821.     jbe  .ex            ; pa-min
  822.   .noa:
  823.     cmp  ebx,ecx
  824.     ja   .nob
  825.     mov  eax,[esp+16]
  826.     jmp  .ex2
  827.   .nob:
  828.     mov  eax,[esp+24]
  829.   .ex2:
  830.     mov  [esp+28],eax
  831.   .ex:
  832.     popa
  833.     add  [edi],al
  834.     inc  esi
  835.     inc  edi
  836.     pop  ecx
  837.     loop .lpaeth
  838.     popa
  839.     jmp  PngFilter.nofilt
  840.  
  841. rb_png: ; eax-dest; ecx-count
  842.     push ecx
  843.     xor  eax,eax
  844.   .shift:
  845.     rol  byte[cur_byte],1
  846.     rcl  eax,1
  847.   .dec:
  848.     dec  [bits]
  849.     jnz  .loop1
  850.   .push:
  851.     push dword[esi]
  852.     pop  [cur_byte]
  853.     mov  [bits],8
  854.     inc  esi
  855.   .loop1:
  856.     loop .shift
  857.     pop  ecx
  858.     ret
  859.  
  860. PngStore:
  861.     push esi
  862.     cmp  [PNG_info.Bit_depth],8
  863.     jbe  .lo
  864.     add  esi,3
  865.   .lo:
  866.   if ~ SYS eq win
  867.     mov  esi,[esi]
  868.     bswap esi
  869.     shr  esi,8
  870.     mov  [edi],esi
  871.     add  edi,3
  872.   else
  873.     movsw
  874.     movsb
  875.   end if
  876.     pop  esi
  877.     ret
  878.  
  879. FiltStats:
  880.     pusha
  881.     xor  ebx,ebx
  882.     mov  edx,23
  883.     mov  ecx,6
  884.   .lp:
  885.     push ecx edx
  886.     Msg  edx
  887.     mov  eax,[filters+ebx*4]
  888.     DebugPrintDec
  889.     pop  edx ecx
  890.     inc  edx
  891.     inc  ebx
  892.     loop .lp
  893.     Newline
  894.     popa
  895.     ret
  896.  
  897.