Subversion Repositories Kolibri OS

Rev

Rev 111 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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