Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1014 diamond 1
;;================================================================================================;;
2
;;//// png.asm //// (c) diamond, 2009 ////////////////////////////////////////////////////////////;;
3
;;================================================================================================;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
8
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
9
;; of the License, or (at your option) any later version.                                         ;;
10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
13
;; Lesser General Public License for more details.                                                ;;
14
;;                                                                                                ;;
15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
17
;;                                                                                                ;;
18
;;================================================================================================;;
19
 
20
;;================================================================================================;;
21
;;proc img.is.png _data, _length ;////////////////////////////////////////////////////////////////;;
22
img.is.png:
23
;;------------------------------------------------------------------------------------------------;;
24
;? Determine if raw data could be decoded (is in PNG format)                                      ;;
25
;;------------------------------------------------------------------------------------------------;;
26
;> _data = raw data as read from file/stream                                                      ;;
27
;> _length = data length                                                                          ;;
28
;;------------------------------------------------------------------------------------------------;;
29
;< eax = false / true                                                                             ;;
30
;;================================================================================================;;
31
; test 1 (length of data)
32
	cmp	dword [esp+8], 8
33
	jb	.nope
34
; test 2: signature
35
	mov	eax, [esp+4]
36
	cmp	dword [eax], 0x474E5089
37
	jne	.nope
38
	cmp	dword [eax+4], 0x0A1A0A0D
39
	je	.yep
40
 
41
  .nope:
42
	xor	eax, eax
43
	ret	8
44
 
45
  .yep:
46
	xor	eax, eax
47
	inc	eax
48
	ret	8
49
;endp
50
 
51
;;================================================================================================;;
1102 diamond 52
;;proc img.decode.png _data, _length, _options ;//////////////////////////////////////////////////;;
1014 diamond 53
img.decode.png:
54
	xor	eax, eax	; .image = 0
55
	pushad
56
	mov	ebp, esp
57
.localsize = 15*4
58
virtual at ebp - .localsize
59
.width		dd	?
60
.height		dd	?
61
.bit_depth	dd	?
62
.color_type	dd	?
63
.bytes_per_pixel dd	?
64
.scanline_len	dd	?
65
.cur_chunk_ptr	dd	?
66
.cur_chunk_size	dd	?
67
.paeth_a	dd	?
68
.paeth_b	dd	?
69
.paeth_c	dd	?
70
.paeth_pa	dd	?
71
.paeth_pb	dd	?
72
.paeth_pc	dd	?
73
.idat_read	dd	?
74
	rb	1Ch
75
.image		dd	?
76
	rd	1
77
.data		dd	?
78
.length		dd	?
1102 diamond 79
.options	dd	?
1014 diamond 80
end virtual
81
	push	0	; .idat_read = 0
82
	sub	esp, .localsize-4
83
; load deflate unpacker, if not yet
84
; acquire mutex
85
@@:
86
	push	1
87
	pop	eax
88
	xchg	[deflate_loader_mutex], eax	; 'xchg' has an implicit 'lock' prefix
89
	test	eax, eax
90
	jz	@f
91
	mcall	5, 1
92
	jmp	@b
93
@@:
94
	cmp	[deflate_unpack2], __deflate_unpack2_import_name__
95
	jnz	.deflate_loaded
96
; do loading
97
	invoke	dll.load, @IMPORT
98
	test	eax, eax
99
	jz	.deflate_loaded
100
	add	esp, .localsize
101
	popad
102
	mov	[deflate_loader_mutex], eax
1102 diamond 103
	ret	12
1014 diamond 104
.deflate_loaded:
105
; release mutex
106
	mov	[deflate_loader_mutex], 0
107
; ok, continue
108
	mov	esi, [.data]		; esi -> data
109
	mov	ecx, [.length]		; ecx = length
110
; the signature has been already checked in img.is.png
111
	lodsd
112
	lodsd
113
	sub	ecx, 8
114
	xor	ebx, ebx	; no image allocated
115
.chunks_loop:
116
	sub	ecx, 12
117
	jc	.eof
118
	lodsd	; chunk length
119
	bswap	eax
120
	sub	ecx, eax
121
	jc	.eof
122
	push	ecx	; save length of data rest
123
	xchg	eax, ecx	; ecx = size of data in the chunk
124
	lodsd	; chunk type
125
	cmp	eax, 'IHDR'
126
	jz	.ihdr
127
	cmp	eax, 'IDAT'
128
	jz	.idat
129
	cmp	eax, 'IEND'
130
	jz	.iend
131
	cmp	eax, 'PLTE'
132
	jz	.palette
133
; unrecognized chunk, ignore
134
	lea	esi, [esi+ecx+4]
135
	pop	ecx
136
	jmp	.chunks_loop
137
; IHDR chunk
138
.ihdr:
139
	cmp	ecx, 13
140
	jnz	.invalid_chunk
141
	cmp	[.image], 0
142
	jnz	.invalid_chunk
143
; read image characteristics
144
	lodsd
145
	bswap	eax
146
	mov	[.width], eax
147
	lodsd
148
	bswap	eax
149
	mov	[.height], eax
150
	xor	eax, eax
151
	lea	ebx, [eax+1]
152
	lodsb
153
	cmp	al, 16
154
	ja	.invalid_chunk
155
	test	al, al
156
	jz	.invalid_chunk
157
	lea	edx, [eax-1]
158
	test	al, dl
159
	jnz	.invalid_chunk
160
	mov	[.bit_depth], eax
161
	lodsb
162
	test	al, not 7
163
	jnz	.invalid_chunk
164
	mov	[.color_type], eax
165
	lodsb
166
	test	al, al
167
	jnz	.invalid_chunk	; only compression method 0 is defined
168
	lodsb
169
	test	al, al
170
	jnz	.invalid_chunk	; only filtering method 0 is defined
171
	lodsb
172
	test	al, al
173
	jnz	.invalid_chunk	; progressive PNGs are not supported yet
174
; check for correctness and calculate bytes_per_pixel and scanline_len
175
	mov	eax, [.bit_depth]
176
	mov	edx, [.color_type]
177
	dec	edx
178
	js	.grayscale1
179
	dec	edx
180
	jz	.rgb1
181
	dec	edx
182
	jz	.palette1
183
	dec	edx
184
	jz	.grayscale_alpha1
185
	dec	edx
186
	dec	edx
187
	jnz	.invalid_chunk
188
.rgb_alpha1:
189
	inc	ebx
190
.rgb1:
191
	inc	ebx
192
.grayscale_alpha1:
193
	inc	ebx
194
	cmp	al, 8
195
	jb	.invalid_chunk
196
	jmp	@f
197
.palette1:
198
	cmp	al, 8
199
	ja	.invalid_chunk
200
.grayscale1:
201
@@:
202
	mul	ebx
203
	push	eax
204
	add	eax, 7
205
	shr	eax, 3
206
	mov	[.bytes_per_pixel], eax
207
	pop	eax
208
	mul	[.width]
209
	add	eax, 7
210
	shr	eax, 3
211
	mov	[.scanline_len], eax
212
; allocate image
213
	push	Image.bpp24
214
	pop	eax
215
	cmp	[.color_type], 2
216
	jz	@f
217
	mov	al, Image.bpp32
218
	cmp	[.color_type], 6
219
	jz	@f
220
	mov	al, Image.bpp8
221
@@:
222
	stdcall	img.create, [.width], [.height], eax
223
	test	eax, eax
224
	jz	.invalid_chunk
225
	mov	[.image], eax
226
	jmp	.next_chunk
227
.invalid_chunk:
228
.iend:
229
	pop	ecx
230
.eof:
231
	add	esp, .localsize
232
	popad
1102 diamond 233
	ret	12
1014 diamond 234
; PLTE chunk
235
.palette:
236
	mov	eax, [.image]
237
	test	eax, eax
238
	jz	.invalid_chunk
239
	cmp	[.color_type], 3
240
	jz	.copy_palette
241
.ignore_chunk:
242
	add	esi, ecx
243
.next_chunk:
244
	lodsd
245
	pop	ecx
246
	jmp	.chunks_loop
247
.copy_palette:
248
	mov	edi, [eax + Image.Palette]
249
	xor	eax, eax
250
	cmp	ecx, 256*3
251
	ja	.next_chunk
252
@@:
253
	sub	ecx, 3
254
	jz	@f
255
	js	.invalid_chunk
256
	lodsd
257
	dec	esi
258
	bswap	eax
259
	shr	eax, 8
260
	stosd
261
	jmp	@b
262
@@:
263
	lodsd
264
	dec	esi
265
	bswap	eax
266
	shr	eax, 8
267
	stosd
268
	jmp	.next_chunk
269
.idat:
270
	jecxz	.next_chunk
271
	cmp	[.idat_read], 0
272
	jnz	@f
273
	lodsb
274
	inc	[.idat_read]
275
	and	al, 0xF
276
	cmp	al, 8
277
	jnz	.invalid_chunk
278
	dec	ecx
279
	jz	.next_chunk
280
@@:
281
	cmp	[.idat_read], 1
282
	jnz	@f
283
	lodsb
284
	inc	[.idat_read]
285
	test	al, 20h
286
	jnz	.invalid_chunk
287
	dec	ecx
288
	jz	.next_chunk
289
@@:
290
	mov	[.cur_chunk_ptr], esi
291
	mov	[.cur_chunk_size], ecx
292
	pop	[.length]
293
	push	eax
294
	push	esp
295
	push	ebp
296
	push	.deflate_callback
297
	call	[deflate_unpack2]
298
	pop	ecx
299
	test	eax, eax
300
	jz	.invalid_chunk
301
; convert PNG unpacked data to RAW data
302
	mov	esi, eax
303
	push	eax ecx
304
; unfilter
305
	mov	edx, [.height]
306
.unfilter_loop_e:
307
	mov	ebx, [.scanline_len]
308
	sub	ecx, 1
309
	jc	.unfilter_done
310
	sub	ecx, ebx
311
	jc	.unfilter_done
312
	movzx	eax, byte [esi]
313
	add	esi, 1
314
	cmp	eax, 4
315
	ja	.next_scanline
316
	jmp	dword [@f + eax*4]
317
align 4
318
@@:
319
	dd	.unfilter_none
320
	dd	.unfilter_sub
321
	dd	.unfilter_up
322
	dd	.unfilter_average
323
	dd	.unfilter_paeth
324
.unfilter_sub:
325
	mov	edi, [.bytes_per_pixel]
326
	add	esi, edi
327
	sub	ebx, edi
328
	jbe	.next_scanline
329
	neg	edi
330
@@:
331
	mov	al, [esi+edi]
332
	add	[esi], al
333
	add	esi, 1
334
	sub	ebx, 1
335
	jnz	@b
336
	jmp	.next_scanline
337
.unfilter_up:
338
	cmp	edx, [.height]
339
	jz	.unfilter_none
340
	lea	edi, [ebx+1]
341
	neg	edi
342
@@:
343
	mov	al, [esi+edi]
344
	add	[esi], al
345
	add	esi, 1
346
	sub	ebx, 1
347
	jnz	@b
348
	jmp	.next_scanline
349
.unfilter_average:
350
	mov	edi, [.bytes_per_pixel]
351
	cmp	edx, [.height]
352
	jz	.unfilter_average_firstline
353
	push	edx
354
	lea	edx, [ebx+1]
355
	neg	edx
356
	sub	ebx, edi
357
@@:
358
	mov	al, [esi+edx]
359
	shr	al, 1
360
	add	[esi], al
361
	add	esi, 1
362
	sub	edi, 1
363
	jnz	@b
364
	mov	edi, [.bytes_per_pixel]
365
	neg	edi
366
	test	ebx, ebx
367
	jz	.unfilter_average_done
368
@@:
369
	mov	al, [esi+edx]
370
	add	al, [esi+edi]
371
	rcr	al, 1
372
	add	[esi], al
373
	add	esi, 1
374
	sub	ebx, 1
375
	jnz	@b
376
.unfilter_average_done:
377
	pop	edx
378
	jmp	.next_scanline
379
.unfilter_average_firstline:
380
	mov	edi, [.bytes_per_pixel]
381
	add	esi, edi
382
	sub	ebx, edi
383
	jbe	.next_scanline
384
	neg	edi
385
@@:
386
	mov	al, [esi+edi]
387
	shr	al, 1
388
	add	[esi], al
389
	add	esi, 1
390
	sub	ebx, 1
391
	jnz	@b
392
	jmp	.unfilter_none
393
.unfilter_paeth:
394
	cmp	edx, [.height]
395
	jz	.unfilter_sub
396
	push	edx
397
	lea	edx, [ebx+1]
398
	mov	edi, [.bytes_per_pixel]
399
	neg	edx
400
	sub	ebx, edi
401
@@:
402
	mov	al, [esi+edx]
403
	add	[esi], al
404
	add	esi, 1
405
	sub	edi, 1
406
	jnz	@b
407
	mov	edi, [.bytes_per_pixel]
408
	neg	edi
409
	test	ebx, ebx
410
	jz	.unfilter_paeth_done
411
	push	ecx
412
@@:
413
	push	ebx
414
; PaethPredictor(Raw(x-bpp) = a, Prior(x) = b, Prior(x-bpp) = c)
415
	movzx	eax, byte [esi+edi]
416
	mov	[.paeth_a], eax
417
	movzx	ecx, byte [esi+edx]
418
	add	edi, edx
419
	mov	[.paeth_b], ecx
420
	add	ecx, eax
421
	movzx	eax, byte [esi+edi]
422
	mov	[.paeth_c], eax
423
	sub	ecx, eax	; ecx = a + b - c = p
424
; calculate pa = abs(p-a), pb = abs(p-b), pc = abs(p-c)
425
	mov	ebx, ecx
426
	sub	ebx, eax	; ebx = p - c
427
	cmp	ebx, 80000000h
428
	sbb	eax, eax	; eax = (p < c) ? 0 : 0xFFFFFFF
429
	not	eax		; eax = (p < c) ? 0xFFFFFFFF : 0
430
	and	eax, ebx	; eax = (p < c) ? p - c : 0
431
	sub	ebx, eax
432
	sub	ebx, eax	; ebx = abs(p-c)
433
	mov	[.paeth_pc], ebx
434
	mov	ebx, ecx
435
	sub	ebx, [.paeth_a]
436
	cmp	ebx, 80000000h
437
	sbb	eax, eax
438
	not	eax
439
	and	eax, ebx
440
	sub	ebx, eax
441
	sub	ebx, eax
442
	mov	[.paeth_pa], ebx
443
	mov	ebx, ecx
444
	sub	ebx, [.paeth_b]
445
	cmp	ebx, 80000000h
446
	sbb	eax, eax
447
	not	eax
448
	and	eax, ebx
449
	sub	ebx, eax
450
	sub	ebx, eax
451
	;mov	[.paeth_pb], ebx
452
; select closest value
453
	push	edx
454
	mov	edx, [.paeth_b]
455
	sub	edx, [.paeth_a]
456
	sub	ebx, [.paeth_pa]
457
	sbb	ecx, ecx	; ecx = (pa > pb) ? 0xFFFFFFFF : 0
458
	sbb	eax, eax	; eax = (pa > pb) ? 0xFFFFFFFF : 0
459
	and	ecx, ebx	; ecx = (pa > pb) ? pb - pa : 0
460
	and	eax, edx	; eax = (pa > pb) ? b - a : 0
461
	add	ecx, [.paeth_pa]	; ecx = (pa > pb) ? pb : pa = min(pa,pb)
462
	add	eax, [.paeth_a]		; eax = (pa > pb) ? b : a
463
	mov	edx, [.paeth_c]
464
	sub	edx, eax
465
	sub	[.paeth_pc], ecx
466
	sbb	ebx, ebx	; ebx = (min(pa,pb) <= pc) ? 0 : 0xFFFFFFFF
467
	and	ebx, edx	; ebx = (min(pa,pb) <= pc) ? 0 : c - eax
468
	add	eax, ebx
469
	pop	edx
470
	add	[esi], al
471
	pop	ebx
472
	sub	edi, edx
473
	add	esi, 1
474
	sub	ebx, 1
475
	jnz	@b
476
	pop	ecx
477
.unfilter_paeth_done:
478
	pop	edx
479
	jmp	.next_scanline
480
.unfilter_none:
481
	add	esi, ebx
482
.next_scanline:
483
	sub	edx, 1
484
	jnz	.unfilter_loop_e
485
.unfilter_done:
486
; unfiltering done, now convert to raw data
487
	pop	ebx esi
488
	push	esi
489
	mov	edx, [.height]
490
	mov	eax, [.image]
491
	mov	edi, [eax + Image.Data]
492
	cmp	[.color_type], 0
493
	jz	.grayscale2
494
	cmp	[.color_type], 2
495
	jz	.rgb2
496
	cmp	[.color_type], 3
497
	jz	.palette2
498
	cmp	[.color_type], 4
499
	jz	.grayscale_alpha2
500
.rgb_alpha2:
501
	cmp	[.bit_depth], 16
502
	jz	.rgb_alpha2_16bit
503
.rgb_alpha2.next:
504
	mov	ecx, [.scanline_len]
505
	sub	ebx, 1
506
	jc	.convert_done
507
	add	esi, 1
508
	sub	ebx, ecx
509
	jc	.convert_done
510
@@:
511
	mov	al, [esi+2]
512
	mov	[edi], al
513
	mov	al, [esi+1]
514
	mov	[edi+1], al
515
	mov	al, [esi]
516
	mov	[edi+2], al
517
	mov	al, [esi+3]
518
	mov	[edi+3], al
1079 diamond 519
	add	esi, 4
520
	add	edi, 4
1014 diamond 521
	sub	ecx, 4
522
	jnz	@b
523
	sub	edx, 1
524
	jnz	.rgb_alpha2.next
525
	jmp	.convert_done
526
.rgb_alpha2_16bit:
527
	mov	ecx, [.scanline_len]
528
	sub	ebx, 1
529
	jc	.convert_done
530
	add	esi, 1
531
	sub	ebx, ecx
532
	jc	.convert_done
533
.rgb_alpha2.loop:
534
 
535
; convert 16 bit sample to 8 bit sample
536
macro convert_16_to_8
537
{
538
local .l1,.l2
539
	xor	ah, 0x80
540
	js	.l1
541
	cmp	al, ah
542
	adc	al, 0
543
	jmp	.l2
544
.l1:
545
	cmp	ah, al
546
	sbb	al, 0
547
.l2:
548
}
549
 
550
	mov	ax, [esi+4]
551
	convert_16_to_8
552
	mov	[edi], al
553
	mov	ax, [esi+2]
554
	convert_16_to_8
555
	mov	[edi+1], al
556
	mov	ax, [esi]
557
	convert_16_to_8
558
	mov	[edi+2], al
559
	;mov	ax, [esi+6]
560
	;convert_16_to_8
561
	;mov	[edi+3], al
562
	add	esi, 8
563
	add	edi, 4
564
	sub	ecx, 8
565
	jnz	.rgb_alpha2.loop
566
	sub	edx, 1
567
	jnz	.rgb_alpha2_16bit
568
	jmp	.convert_done
569
.grayscale2:
570
	push	edi edx
571
	mov	edi, [eax + Image.Palette]
572
	mov	ecx, [.bit_depth]
573
	cmp	cl, 16
574
	jnz	@f
575
	mov	cl, 8
576
@@:
577
	push	1
578
	pop	eax
579
	shl	eax, cl
580
	xchg	eax, ecx
581
	mov	edx, 0x010101
582
	cmp	al, 8
583
	jz	.graypal_common
584
	mov	edx, 0x111111
585
	cmp	al, 4
586
	jz	.graypal_common
587
	mov	edx, 0x555555
588
	cmp	al, 2
589
	jz	.graypal_common
590
	mov	edx, 0xFFFFFF
591
.graypal_common:
592
	xor	eax, eax
593
@@:
594
	stosd
595
	add	eax, edx
596
	loop	@b
597
	pop	edx edi
598
	cmp	[.bit_depth], 16
599
	jz	.grayscale2_16bit
600
.palette2:
601
	cmp	[.bit_depth], 1
602
	jz	.palette2_1bit
603
	cmp	[.bit_depth], 2
604
	jz	.palette2_2bit
605
	cmp	[.bit_depth], 4
606
	jz	.palette2_4bit
607
.palette2_8bit:
608
	mov	ecx, [.scanline_len]
609
	sub	ebx, 1
610
	jc	.convert_done
611
	add	esi, 1
612
	sub	ebx, ecx
613
	jc	.convert_done
614
	push	ecx
615
	shr	ecx, 2
616
	rep	movsd
617
	pop	ecx
618
	and	ecx, 3
619
	rep	movsb
620
	sub	edx, 1
621
	jnz	.palette2_8bit
622
	jmp	.convert_done
623
.palette2_4bit:
624
	sub	ebx, 1
625
	jc	.convert_done
626
	add	esi, 1
627
	sub	ebx, [.scanline_len]
628
	jc	.convert_done
629
	push	edx
630
	mov	ecx, [.width]
631
@@:
632
	mov	al, [esi]
633
	add	esi, 1
634
	mov	dl, al
635
	shr	al, 4
636
	and	dl, 0xF
637
	mov	[edi], al
638
	sub	ecx, 1
639
	jz	@f
640
	mov	[edi+1], dl
641
	add	edi, 2
642
	sub	ecx, 1
643
	jnz	@b
644
	sub	edi, 1
645
@@:
646
	pop	edx
647
	add	edi, 1
648
	sub	edx, 1
649
	jnz	.palette2_4bit
650
	jmp	.convert_done
651
.palette2_2bit:
652
	sub	ebx, 1
653
	jc	.convert_done
654
	add	esi, 1
655
	sub	ebx, [.scanline_len]
656
	jc	.convert_done
657
	push	edx
658
	mov	ecx, [.width]
659
@@:
660
	mov	al, [esi]
661
	add	esi, 1
662
	mov	dl, al
663
	shr	al, 6
664
	and	dl, not 11000000b
665
	mov	[edi], al
666
	add	edi, 1
667
	sub	ecx, 1
668
	jz	@f
669
	mov	al, dl
670
	shr	dl, 4
671
	and	al, not 00110000b
672
	mov	[edi], dl
673
	add	edi, 1
674
	sub	ecx, 1
675
	jz	@f
676
	mov	dl, al
677
	shr	al, 2
678
	and	dl, not 00001100b
679
	mov	[edi], al
680
	add	edi, 1
681
	sub	ecx, 1
682
	jz	@f
683
	mov	[edi], dl
684
	add	edi, 1
685
	sub	ecx, 1
686
	jnz	@b
687
@@:
688
	pop	edx
689
	sub	edx, 1
690
	jnz	.palette2_2bit
691
	jmp	.convert_done
692
.palette2_1bit:
693
	sub	ebx, 1
694
	jc	.convert_done
695
	add	esi, 1
696
	sub	ebx, [.scanline_len]
697
	jc	.convert_done
698
	push	edx
699
	mov	ecx, [.width]
700
@@:
701
	mov	al, [esi]
702
	add	esi, 1
703
repeat 3
704
	mov	dl, al
705
	shr	al, 9-%*2
706
	and	dl, not (1 shl (9-%*2))
707
	mov	[edi], al
708
	add	edi, 1
709
	sub	ecx, 1
710
	jz	@f
711
	mov	al, dl
712
	shr	dl, 8-%*2
713
	and	al, not (1 shl (8-%*2))
714
	mov	[edi], dl
715
	add	edi, 1
716
	sub	ecx, 1
717
	jz	@f
718
end repeat
719
	mov	dl, al
720
	shr	al, 1
721
	and	dl, not (1 shl 1)
722
	mov	[edi], al
723
	add	edi, 1
724
	sub	ecx, 1
725
	jz	@f
726
	mov	[edi], dl
727
	add	edi, 1
728
	sub	ecx, 1
729
	jnz	@b
730
@@:
731
	pop	edx
732
	sub	edx, 1
733
	jnz	.palette2_1bit
734
	jmp	.convert_done
735
.grayscale2_16bit:
736
	mov	ecx, [.scanline_len]
737
	sub	ebx, 1
738
	jc	.convert_done
739
	add	esi, 1
740
	sub	ebx, ecx
741
	jc	.convert_done
742
@@:
1079 diamond 743
	mov	ax, [esi]
744
	add	esi, 2
1014 diamond 745
	convert_16_to_8
1079 diamond 746
	mov	[edi], al
1014 diamond 747
	add	edi, 1
748
	sub	ecx, 2
749
	jnz	@b
750
	sub	edx, 1
751
	jnz	.grayscale2_16bit
752
	jmp	.convert_done
753
.rgb2:
754
	cmp	[.bit_depth], 16
755
	jz	.rgb2_16bit
756
.rgb2.next:
757
	mov	ecx, [.scanline_len]
758
	sub	ebx, 1
759
	jc	.convert_done
760
	add	esi, 1
761
	sub	ebx, ecx
762
	jc	.convert_done
763
@@:
764
	mov	al, [esi+2]
765
	mov	[edi], al
766
	mov	al, [esi+1]
767
	mov	[edi+1], al
768
	mov	al, [esi]
769
	mov	[edi+2], al
770
	add	esi, 3
771
	add	edi, 3
772
	sub	ecx, 3
773
	jnz	@b
774
	sub	edx, 1
775
	jnz	.rgb2.next
776
	jmp	.convert_done
777
.rgb2_16bit:
778
	mov	ecx, [.scanline_len]
779
	sub	ebx, 1
780
	jc	.convert_done
781
	add	esi, 1
782
	sub	ebx, ecx
783
	jc	.convert_done
784
.rgb2.loop:
785
	mov	ax, [esi+4]
786
	convert_16_to_8
787
	mov	[edi], al
788
	mov	ax, [esi+2]
789
	convert_16_to_8
790
	mov	[edi+1], al
791
	mov	ax, [esi]
792
	convert_16_to_8
793
	mov	[edi+2], al
794
	add	esi, 6
795
	add	edi, 3
796
	sub	ecx, 6
797
	jnz	.rgb2.loop
798
	sub	edx, 1
799
	jnz	.rgb2_16bit
800
	jmp	.convert_done
801
.grayscale_alpha2:
802
	cmp	[.bit_depth], 16
803
	jz	.grayscale_alpha2_16bit
804
.grayscale_alpha2.next:
805
	mov	ecx, [.scanline_len]
806
	sub	ebx, 1
807
	jc	.convert_done
808
	add	esi, 1
809
	sub	ebx, ecx
810
	jc	.convert_done
811
@@:
812
	mov	al, [esi]
813
	mov	[edi], al
814
	add	esi, 2
815
	add	edi, 1
816
	sub	ecx, 2
817
	jnz	@b
818
	sub	edx, 1
819
	jnz	.grayscale_alpha2.next
820
	jmp	.convert_done
821
.grayscale_alpha2_16bit:
822
	mov	ecx, [.scanline_len]
823
	sub	ebx, 1
824
	jc	.convert_done
825
	add	esi, 1
826
	sub	ebx, ecx
827
	jc	.convert_done
828
@@:
1079 diamond 829
	mov	ax, [esi]
830
	add	esi, 4
1014 diamond 831
	convert_16_to_8
1079 diamond 832
	mov	[edi], al
1014 diamond 833
	add	edi, 1
834
	sub	ecx, 4
835
	jnz	@b
836
	sub	edx, 1
837
	jnz	.grayscale_alpha2_16bit
838
.convert_done:
839
	pop	ecx
840
	mcall	68, 13
841
	mov	esi, [.cur_chunk_ptr]
842
	add	esi, [.cur_chunk_size]
843
	push	[.length]
844
	jmp	.next_chunk
845
 
846
.deflate_callback:
847
	mov	ebp, [esp+4]
848
	mov	ebx, [esp+8]
849
	xor	eax, eax
850
	mov	esi, [.cur_chunk_size]
851
	mov	[ebx], esi
852
	test	esi, esi
853
	jz	.deflate_callback.ret
854
	mov	eax, [.cur_chunk_ptr]
855
	mov	ecx, [.length]
856
	add	esi, eax
857
	mov	[.cur_chunk_ptr], esi
858
	and	[.cur_chunk_size], 0
859
@@:
860
	sub	ecx, 12
861
	jb	.deflate_callback.ret
862
	cmp	dword [esi+4+4], 'IDAT'
863
	jnz	.deflate_callback.ret
864
	mov	edx, [esi+4]
865
	bswap	edx
866
	sub	ecx, edx
867
	jb	.deflate_callback.ret
868
	add	esi, 4+8
869
	test	edx, edx
870
	jz	@b
871
	mov	[.cur_chunk_size], edx
872
	mov	[.cur_chunk_ptr], esi
873
	mov	[.length], ecx
874
.deflate_callback.ret:
875
	ret	8
876
;endp
877
 
878
img.encode.png:
879
	xor	eax, eax
1102 diamond 880
	ret	12