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 main algorythm
2
; Written in pure assembler by Ivushkin Andrey aka Willow
3
 
4
macro get_a _type,_size,c1,c2,c3,c4,c5
5
{
6
get_#_type:
7
local .no,.no0,.ex
8
    push edx
9
    and  [Flags],not 1
10
if _type eq Len
11
    cmp  eax,c4
12
    jne   .no
13
    mov  eax,c5
14
    jmp  .ex
15
   .no:
16
end if
17
    sub  eax,c1
18
    ja   .no0
19
    add  eax,c2
20
    jmp  .ex
21
   .no0:
22
    add  eax,c3
23
    push eax
24
    mov  ecx,eax
25
    shr  ecx,_size
26
    xor  eax,eax
27
    call read_bits
28
    pop  edx
29
    and  edx,1 shl _size-1
30
    shl  edx,cl
31
    movzx ecx,[tblH#_type+ecx*2]
32
    add  edx,ecx
33
    add  eax,edx
34
   .ex:
35
    or  [Flags],1
36
    pop  edx
37
    ret
38
}
39
; *************************
40
 
41
Deflate:
42
    mov  edi,[outp]
43
  .init:
44
    mov  [bits],8
45
    lodsb
46
    call setcurb
47
  .blkbegin:
48
    and  [lastblk],0
49
    and  [Flags],not 1
50
    rbits 0,1
51
    test eax,eax
52
    je  .nolast
53
    mov  [lastblk],1
54
  .nolast:
55
    rbits 0,2
56
    cmp  eax,10b
57
    je   .DynHuff
58
    cmp  eax,01b
59
    je   .static
60
    test eax,eax
61
    jnz  .errorID
62
    Msg  30
63
    movzx ecx,[bits]
64
    call read_bits
65
    movzx ecx,word[esi-1]
66
    add  esi,3
67
    rep  movsb
68
    jmp  .check_last
69
  .errorID:
70
    Msg  6
71
    ret
72
; Static Huffman
73
  .static:
74
if SHOW_METH eq 1
75
    Msg  20
76
end if
77
    mov  edi,[outp]
78
    or  [Flags],1
79
  .next:
80
    rbits 0,7
81
;    stop
82
    cmp  eax,0x17
83
    ja   .no7
84
    add  eax,256
85
    cmp  eax,256
86
    jne  .noend
87
  .check_last:
88
    mov  [outp],edi
89
    cmp  [lastblk],1
90
    je   .ex
91
    jmp  .blkbegin
92
   .noend:
93
    call get_Len
94
    mov  ebx,eax
95
    rbits 0,5
96
    call get_Dist
97
    neg  eax
98
    push esi
99
    lea  esi,[edi+eax]
100
    mov  ecx,ebx
101
    rep  movsb
102
    pop  esi
103
    jmp  .next
104
   .no7:
105
    rbits eax,1
106
    cmp  eax,0xc8
107
    jb   .no9
108
    rbits eax,1
109
    sub  eax,0xd0
110
    jmp  .no81
111
  .no9:
112
    cmp  eax,0xc0
113
    jb   .no81
114
    add  eax,0x58
115
    jmp  .noend
131 diamond 116
  .no81:
31 halyavin 117
    sub  eax,0x30
118
    stosb
119
    jmp .next
120
  .ex:
121
    ret
122
; ************* dynamic Huffman ************
123
 
124
.DynHuff:
125
;    dps  '##'
126
if SHOW_METH eq 1
127
    Msg  19
128
end if
129
    pusha
130
    xor  eax,eax
131 diamond 131
    mov  ecx,(output-bl_count) / 4
31 halyavin 132
    mov  edi,bl_count
133
    rep  stosd
134
    popa
135
 
136
; max_len=0
137
    and  [max_len],0
138
    rbits 0,5
139
; hlit-257
140
    add  eax,257
141
    mov  [hlit],ax
142
    rbits 0,5
143
; hdist-1
144
    inc  eax
145
    mov  [hdist],al
146
    rbits 0,4
147
; hclen-4
148
    add  eax,4
149
    mov  [hclen],al
150
    mov  ecx,eax
151
    push edi
152
    mov  edi,tmp_clit
153
; read  code lengths for code lengths
154
  .alphloop:
155
    push ecx
156
    rbits 0,3
157
    stosb
158
    pop  ecx
159
    loop .alphloop
160
; sort code lengths for code lengths
161
    push esi
162
    movzx ecx,[hclen]
163
    xor  eax,eax
164
    mov  edi,tmp_clit
165
    mov  esi,tblSort
166
  .sortloop:
167
    lodsb
168
    movzx bx,byte[edi]
169
    mov  [sorted_clit+eax*2],bx
170
    inc  edi
171
    loop .sortloop
172
    pop  esi edi
173
.generate:
174
    mov  ecx,19
175
    mov  ebx,calph
176
    mov  edx,seql
177
    mov  eax,sorted_clit
178
    call Huffc
179
    and  [tblCount],0
180
    or  [Flags],1
181
    mov  edi,Lit_c
182
    mov  ebp,sorted_clit
183
   .again:
184
    cmp  edi,output+OUTBUF
185
    jb   ._ok
186
    Msg  16
187
    jmp  .ex
188
  ._ok:
189
    mov  edx,seql
190
    mov  ebx,calph
191
    call get_code
192
    call ExpLen
193
    cmp  [hlit],ax
194
    ja   .again
195
if SHOW_CHARS eq 1
196
    mov  edi,Lit_c
197
    call Show_codes
198
end if
199
    mov  edi,Dist_c
200
    and  [tblCount],0
201
   .again2:
202
    mov  ebx,calph
203
 
204
    call get_code
205
    call ExpLen
206
    cmp  [hdist],al
207
    ja   .again2
208
    movzx ecx,[hlit]
209
    mov  ebx,Literal
210
    mov  edx,seql
211
    mov  eax,Lit_c
212
    call Huffc
213
    movzx ecx,[hdist]
214
    mov  ebx,Distance
215
    mov  edx,seqd
216
    mov  eax,Dist_c
217
    call Huffc
218
 
219
    push [hlit]
220
    pop  [tblLen]
221
    mov  ebp,Lit_c
222
    mov  edx,seql
223
    mov  ebx,Literal
224
    mov  edi,[outp]
225
    and  [tblCount],0
226
  .again3:               ; <------------
227
    call get_code
228
    cmp  eax,256
229
    je   .check_last
230
    ja   .dist
231
    stosb
232
    jmp  .again3
233
  .dist:
234
    call get_Len
235
    push eax ebx edx ebp
236
    mov  ecx,32
237
    mov  ebp,Dist_c
238
    mov  edx,seqd
239
    mov  ebx,Distance
240
    mov  [tblLen],32
241
    call get_code
242
    call get_Dist
243
    push [hlit]
244
    pop  [tblLen]
245
    neg  eax
246
    pop  ebp edx ebx ecx
247
    push esi
248
    lea  esi,[edi+eax]
249
    rep  movsb
250
    pop  esi
251
    jmp  .again3
252
 
253
; ******************************************
254
Huffc:
255
; EBX - dest array, ECX - length, EDX - br_seq dest, EAX - source array
256
    push esi edi eax ecx
257
    mov  edi,bl_count
258
    xor  eax,eax
259
    mov  ecx,BITS
260
    rep  stosw
261
    pop  ecx
262
    mov  esi,[esp]
263
    mov  [tblLen],cx
264
    mov  [max_len],ax
265
; Count the number of codes for each code length
266
  .cnt_loop:
267
    lodsw
268
    cmp  [max_len],ax
269
    jae  .skip
270
    mov  [max_len],ax
271
  .skip:
272
    inc  byte[bl_count+eax]
273
    loop .cnt_loop
274
    movzx ecx,[max_len]
275
    xor  eax,eax
276
    and  [bl_count],al
277
    xor  esi,esi   ; edx - bits
278
    mov  edi,next_code+2
279
    push ebx
280
; Find the numerical value of the smallest code for each code length
281
  .nc_loop:
282
    movzx bx,byte[bl_count+esi]
283
    add  ax,bx
284
    shl  ax,1
285
    stosw
286
    inc  esi
287
    loop .nc_loop
288
    pop  ebx
289
; clear table
290
    movzx ecx,[tblLen]
291
    xor  eax,eax
292
    dec  eax
293
    mov  edi,ebx
294
    rep  stosw
295
    inc  eax
296
    movzx ecx,[tblLen]
297
    mov  esi,[esp]
298
    mov  edi,ebx
299
; Assign numerical values to all codes
300
  .loop3:
301
    lodsw
302
    test eax,eax
303
    jz   .lp
304
    push [next_code+eax*2]
305
    pop  word[edi]
306
    inc  [next_code+eax*2]
307
  .lp:
308
    add  edi,2
309
    loop .loop3
310
; Clear all codes
311
    xor  eax,eax
312
    mov  edi,edx
313
    movzx ecx,[max_len]
314
    mov  [edi-1],al
315
; Prepare read bit sequences
316
  .rebiloop:
317
    inc  eax
318
    cmp  [bl_count+eax],0
319
    jz   .sk
320
    stosb
321
    inc  byte[edx-1]
322
  .sk:
323
    loop .rebiloop
324
    movzx ecx,byte[edx-1]
325
    dec  ecx
326
    jecxz .noreb2
327
  .reb2loop:
328
    mov  al,[edx+ecx-1]
329
    sub  [edx+ecx],al
330
    loop .reb2loop
331
  .noreb2:
332
    pop  eax edi esi
333
    ret
334
 
335
; ******************************************
336
 
337
; get Codes of variable sizes
338
get_code:
339
; EDX - br_seq, EBX - source table, EBP - codelength table
340
    push edx edi
341
    xor  eax,eax
342
    movzx ecx,byte[edx-1]
343
    mov  [codel],ax
344
   .rb3:
345
    push ecx
346
    movzx ecx,byte[edx]
347
    add  [codel],cx
348
    call read_bits
349
    movzx ecx,[tblLen]
350
    inc  ecx
351
    mov  edi,ebx
352
   .scas:
353
    repne scasw
354
    jecxz .notfound
355
    push edi ecx
356
    sub  edi,ebx
357
    sub  edi,2
358
    mov  cx,[codel]
359
    cmp  cx,[ds:ebp+edi]
360
    jne  .notfound2
361
    mov  eax,edi
362
    shr  eax,1
363
    add  esp,12
364
   .pp:
365
    pop  edi edx
366
    ret
367
   .notfound2:
368
    pop  ecx
369
    pop  edi
370
    jmp  .scas
371
   .notfound:
372
    pop  ecx
373
    inc  edx
374
    loop .rb3
375
    Msg  7
376
    jmp  .pp
377
 
378
codel dw ?
379
; ******************************************
380
ExpLen:
381
    cmp  eax,16
382
    jae  .noliteral
383
    inc  [tblCount]
384
    stosw
385
    jmp  .nomatch
386
  .noliteral:
387
    and  [Flags],not 1
388
    mov  ebx,3
389
    cmp  eax,17
390
    jae  .code1718
391
    mov  ecx,2
392
    xor  eax,eax
393
    call read_bits
394
    lea  ecx,[eax+ebx]
395
    mov  ax,[edi-2]
396
  .cc:
397
    add  [tblCount],cx
398
    rep  stosw
399
    or  [Flags],1
400
    jmp  .nomatch
401
  .code1718:
402
    jne  .code18
403
    mov  ecx,3
404
  .cc2:
405
    xor  eax,eax
406
    call read_bits
407
    lea  ecx,[eax+ebx]
408
    xor  eax,eax
409
    jmp  .cc
410
  .code18:
411
    mov  ebx,11
412
    mov  ecx,7
413
    jmp  .cc2
414
  .nomatch:
415
    mov  ax,[tblCount]
416
    ret
417
get_a Len,2,256+8,10,3,285,258
418
get_a Dist,1,3,4,1
419
 
420
 
421
; ******************************************
422
read_bits: ; eax-dest; ecx-count
423
    push edx ecx
424
  .shift:
425
  if RBLOCK eq 4
426
    ror  [cur_byte],1
427
  else
428
    ror  byte[cur_byte],1
429
  end if
430
    pushf
431
    test [Flags],1
432
    je   .noh1
433
    popf
434
    rcl  eax,1
435
    jmp  .dec
436
  .noh1:
437
    popf
438
    rcr  eax,1
439
  .dec:
440
    dec  [bits]
441
    jnz  .loop1
442
  .push:
443
    push eax
444
    mov  eax,[esi]
445
    call setcurb
446
    pop  eax
447
  if RBLOCK eq 1
448
    inc  esi
449
    inc  [IDATcount]
450
  else
451
    inc  esi
452
    inc  [IDATcount]
453
  end if
454
    cmp  esi,area+INBUF-BSIZE
455
    jbe   .ok
456
    pusha
457
if SHOW_RBLOCK eq 1
458
    Msg  9
459
end if
460
    mov  eax,0
461
    mov  ebx,1
462
    call FileSeek
463
    mov  [esp+4],esi
464
    popa
465
  .ok:
466
    test [Flags],PNG_MODE
467
    jz   .idatok
468
    mov  edx,[IDATcount]
469
    cmp  edx,[IDATsize]
470
    jbe  .idatok
471
    pusha
472
    lodsd
473
    call PngParse.nxt_sec
474
    mov  [IDATcount],1
475
    mov  [esp+4],esi
476
    mov  [esp+20],edx
477
    popa
478
    cmp  edx,21
479
    jne  .idatok
480
    mov  eax,256
481
    pop  ecx
482
    jmp  .exx
483
  .idatok:
484
 
485
    mov  [bits],8
486
  .loop1:
487
    loop .shift2
488
    jmp  .popc
489
  .shift2:
490
    jmp  .shift
491
  .popc:
492
    pop  ecx
493
    test [Flags],1
494
    jne  .exx
495
  .noh2:
496
    rol  eax,cl
497
  .exx:
498
    pop  edx
499
    ret
500
 
501
if SHOW_CHARS eq 1
502
Show_codes:
503
    pusha
504
    movzx ecx,[tblLen]
505
    mov ecx,256
506
    xor  eax,eax
507
  .lp2:
508
    mov  [braces+1],al
509
    push eax ecx
510
    invoke StrFormat,eax,strbuf,20
511
    invoke WriteConsole,[cons],strbuf,16,param1,NULL
512
    invoke WriteConsole,[cons],braces,6,param1,NULL
513
    mov  eax,[esp+4]
514
    movzx  eax,word[edi+eax*2]
515
    test eax,eax
516
    jz     .skip
517
    invoke WriteConsole,[cons],exist,6,param1,NULL
518
  .skip:
519
    invoke WriteConsole,[cons],braces+6,2,param1,NULL
520
    pop  ecx eax
521
    inc  eax
522
    loop .lp
523
    jmp  .ex
524
   .lp:
525
    jmp  .lp2
526
   .ex:
527
    popa
528
    ret
529
 
530
    cons dd ?
531
    param1 dd ?
532
    braces db '( ) = ',0xa, 0xd
533
    strbuf rb 20
534
    exist db 'exists'
535
end if
536
 
537
makeCRC:
538
    pusha
539
    Msg  8
540
    mov  edi,CRC32table
541
    add  edi,255*4
542
    std
543
    mov  ecx,255
544
    mov  ebx,0xedb88320
545
  .m1:
546
    mov  eax,ecx
547
    push ecx
548
    mov  ecx,8
549
  .m2:
550
    shr  eax,1
551
    jnc  .m3
552
    xor  eax,ebx
553
  .m3:
554
    loop .m2
555
    pop  ecx
556
    stosd
557
    loop .m1
558
    popa
559
    cld
560
    ret
561
 
562
UCRC:
563
; in:  esi - data to calculate CRC
564
;      ecx - its length
565
;      [CRC32] - previous CRC32
566
; out: [CRC32]- partial CRC32 (no pre- & post-conditioning!)
567
    pusha
568
    cmp  dword[CRC32table+4],0x77073096
569
    je   .tbl_rdy
570
    call makeCRC
571
  .tbl_rdy:
572
    mov  eax,[CRC32]
573
    not  eax
574
  .m1:
575
    movzx ebx,al
576
    shr  eax,8
577
    xor  bl,[esi]
578
    xor  eax,[CRC32table+ebx*4]
579
    inc  esi
580
    loop .m1
581
    not  eax
582
    mov  [CRC32],eax
583
    popa
584
    ret
585
 
586
UAdler:
587
; in:  esi - data to calculate CRC
588
;      ecx - its length
589
;      [Adler32] - previous Adler32
590
; out: [Adler32]- partial Adler32
591
    pusha
592
    mov  ebp,65521
593
    movzx ebx,word[Adler32] ; s1-ebx
594
    movzx edi,word[Adler32+2] ; s2-edi
595
  .m1:
596
    movzx eax,byte[esi]
597
    add  eax,ebx
598
    xor  edx,edx
599
    div  ebp
600
    mov  ebx,edx
601
    lea  eax,[edi+ebx]
602
    xor  edx,edx
603
    div  ebp
604
    mov  edi,edx
605
    inc  esi
606
    loop .m1
607
    shl  edi,16
608
    add  edi,ebx
609
    mov  [Adler32],edi
610
    popa
611
    ret
612
 
613
tblSort db 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
614
tblHLen dw 7,11,19,35,67,131
615
tblHDist dw 3,5,9,17,33,65,129,257,513,1025,2049,4097,8193,16385