Subversion Repositories Kolibri OS

Rev

Rev 6733 | Rev 8341 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6733 Rev 7279
1
;;================================================================================================;;
1
;;================================================================================================;;
2
;;//// png.asm //// (c) diamond, 2009 ////////////////////////////////////////////////////////////;;
2
;;//// png.asm //// (c) diamond, 2009 ////////////////////////////////////////////////////////////;;
3
;;================================================================================================;;
3
;;================================================================================================;;
4
;;                                                                                                ;;
4
;;                                                                                                ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
5
;; This file is part of Common development libraries (Libs-Dev).                                  ;;
6
;;                                                                                                ;;
6
;;                                                                                                ;;
7
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
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 ;;
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.                                         ;;
9
;; of the License, or (at your option) any later version.                                         ;;
10
;;                                                                                                ;;
10
;;                                                                                                ;;
11
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
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  ;;
12
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
13
;; Lesser General Public License for more details.                                                ;;
13
;; Lesser General Public License for more details.                                                ;;
14
;;                                                                                                ;;
14
;;                                                                                                ;;
15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
16
;; If not, see .                                                    ;;
17
;;                                                                                                ;;
17
;;                                                                                                ;;
18
;;================================================================================================;;
18
;;================================================================================================;;
19
 
19
 
20
include 'libpng/png.asm'
20
include 'libpng/png.asm'
21
 
21
 
22
;;================================================================================================;;
22
;;================================================================================================;;
23
;;proc img.is.png _data, _length ;////////////////////////////////////////////////////////////////;;
23
;;proc img.is.png _data, _length ;////////////////////////////////////////////////////////////////;;
24
img.is.png:
24
img.is.png:
25
;;------------------------------------------------------------------------------------------------;;
25
;;------------------------------------------------------------------------------------------------;;
26
;? Determine if raw data could be decoded (is in PNG format)                                      ;;
26
;? Determine if raw data could be decoded (is in PNG format)                                      ;;
27
;;------------------------------------------------------------------------------------------------;;
27
;;------------------------------------------------------------------------------------------------;;
28
;> _data = raw data as read from file/stream                                                      ;;
28
;> _data = raw data as read from file/stream                                                      ;;
29
;> _length = data length                                                                          ;;
29
;> _length = data length                                                                          ;;
30
;;------------------------------------------------------------------------------------------------;;
30
;;------------------------------------------------------------------------------------------------;;
31
;< eax = false / true                                                                             ;;
31
;< eax = false / true                                                                             ;;
32
;;================================================================================================;;
32
;;================================================================================================;;
33
; test 1 (length of data)
33
; test 1 (length of data)
34
	cmp	dword [esp+8], 8
34
	cmp	dword [esp+8], 8
35
	jb	.nope
35
	jb	.nope
36
; test 2: signature
36
; test 2: signature
37
	mov	eax, [esp+4]
37
	mov	eax, [esp+4]
38
	cmp	dword [eax], 0x474E5089
38
	cmp	dword [eax], 0x474E5089
39
	jne	.nope
39
	jne	.nope
40
	cmp	dword [eax+4], 0x0A1A0A0D
40
	cmp	dword [eax+4], 0x0A1A0A0D
41
	je	.yep
41
	je	.yep
42
 
42
 
43
  .nope:
43
  .nope:
44
	xor	eax, eax
44
	xor	eax, eax
45
	ret	8
45
	ret	8
46
 
46
 
47
  .yep:
47
  .yep:
48
	xor	eax, eax
48
	xor	eax, eax
49
	inc	eax
49
	inc	eax
50
	ret	8
50
	ret	8
51
;endp
51
;endp
52
 
52
 
53
;;================================================================================================;;
53
;;================================================================================================;;
54
;;proc img.decode.png _data, _length, _options ;//////////////////////////////////////////////////;;
54
;;proc img.decode.png _data, _length, _options ;//////////////////////////////////////////////////;;
55
img.decode.png:
55
img.decode.png:
56
	xor	eax, eax	; .image = 0
56
	xor	eax, eax	; .image = 0
57
	pushad
57
	pushad
58
	mov	ebp, esp
58
	mov	ebp, esp
59
.localsize = 29*4
59
.localsize = 29*4
60
virtual at ebp - .localsize
60
virtual at ebp - .localsize
61
.width		dd	?
61
.width		dd	?
62
.height		dd	?
62
.height		dd	?
63
.bit_depth	dd	?
63
.bit_depth	dd	?
64
.color_type	dd	?
64
.color_type	dd	?
65
.bytes_per_pixel dd	?
65
.bytes_per_pixel dd	?
66
.scanline_len	dd	?
66
.scanline_len	dd	?
67
.bits_per_pixel dd	?
67
.bits_per_pixel dd	?
68
.size_rest	dd	?
68
.size_rest	dd	?
69
.cur_chunk_ptr	dd	?
69
.cur_chunk_ptr	dd	?
70
.cur_chunk_size	dd	?
70
.cur_chunk_size	dd	?
71
.allocated	dd	?
71
.allocated	dd	?
72
.paeth_a	dd	?
72
.paeth_a	dd	?
73
.paeth_b	dd	?
73
.paeth_b	dd	?
74
.paeth_c	dd	?
74
.paeth_c	dd	?
75
.paeth_pa	dd	?
75
.paeth_pa	dd	?
76
.paeth_pb	dd	?
76
.paeth_pb	dd	?
77
.paeth_pc	dd	?
77
.paeth_pc	dd	?
78
.i		dd	?
78
.i		dd	?
79
.j		dd	?
79
.j		dd	?
80
; variables to handle interlace
80
; variables to handle interlace
81
.row_distance	dd	?	; diff between two consecutives rows in destination
81
.row_distance	dd	?	; diff between two consecutives rows in destination
82
.col_distance	dd	?	; summand for moving to next row in source
82
.col_distance	dd	?	; summand for moving to next row in source
83
.row_increment	dd	?
83
.row_increment	dd	?
84
.col_increment	dd	?
84
.col_increment	dd	?
85
.block_height	dd	?
85
.block_height	dd	?
86
.block_width	dd	?
86
.block_width	dd	?
87
.interlace	db	?	; 0 if not interlaced, 1 if interlaced
87
.interlace	db	?	; 0 if not interlaced, 1 if interlaced
88
.row_increment_shift db	?
88
.row_increment_shift db	?
89
.col_increment_shift db	?
89
.col_increment_shift db	?
90
.shift		db	?	; shift for current src byte
90
.shift		db	?	; shift for current src byte
91
.starting_row	dd	?
91
.starting_row	dd	?
92
.starting_col	dd	?
92
.starting_col	dd	?
93
.idat_read	dd	?
93
.idat_read	dd	?
94
	rb	1Ch
94
	rb	1Ch
95
.image		dd	?
95
.image		dd	?
96
	rd	1
96
	rd	1
97
.data		dd	?
97
.data		dd	?
98
.length		dd	?
98
.length		dd	?
99
.options	dd	?
99
.options	dd	?
100
end virtual
100
end virtual
101
	push	eax	; .idat_read = 0
101
	push	eax	; .idat_read = 0
102
	push	eax	; .starting_col = 0
102
	push	eax	; .starting_col = 0
103
	push	eax	; .starting_row = 0
103
	push	eax	; .starting_row = 0
104
	push	eax	; .col_increment_shift, .row_increment_shift
104
	push	eax	; .col_increment_shift, .row_increment_shift
105
	inc	eax
105
	inc	eax
106
	push	eax	; .block_width
106
	push	eax	; .block_width
107
	push	eax	; .block_height
107
	push	eax	; .block_height
108
	push	eax	; .col_increment
108
	push	eax	; .col_increment
109
	push	eax	; .row_increment
109
	push	eax	; .row_increment
110
	sub	esp, .localsize-32
110
	sub	esp, .localsize-32
111
; load deflate unpacker, if not yet
111
; load deflate unpacker, if not yet
112
; acquire mutex
112
; acquire mutex
113
@@:
113
@@:
114
	push	1
114
	push	1
115
	pop	eax
115
	pop	eax
116
	xchg	[deflate_loader_mutex], eax	; 'xchg' has an implicit 'lock' prefix
116
	xchg	[deflate_loader_mutex], eax	; 'xchg' has an implicit 'lock' prefix
117
	test	eax, eax
117
	test	eax, eax
118
	jz	@f
118
	jz	@f
119
	mcall	5, 1
119
	mcall	5, 1
120
	jmp	@b
120
	jmp	@b
121
@@:
121
@@:
122
	cmp	[deflate_unpack2], __deflate_unpack2_import_name__
122
	cmp	[deflate_unpack2], __deflate_unpack2_import_name__
123
	jnz	.deflate_loaded
123
	jnz	.deflate_loaded
124
; do loading
124
; do loading
125
	invoke	dll.load, @IMPORT
125
	invoke	dll.load, @IMPORT
126
	test	eax, eax
126
	test	eax, eax
127
	jz	.deflate_loaded
127
	jz	.deflate_loaded
128
	add	esp, .localsize
128
	add	esp, .localsize
129
	popad
129
	popad
130
	mov	[deflate_loader_mutex], eax
130
	mov	[deflate_loader_mutex], eax
131
	ret	12
131
	ret	12
132
.deflate_loaded:
132
.deflate_loaded:
133
; release mutex
133
; release mutex
134
	mov	[deflate_loader_mutex], 0
134
	mov	[deflate_loader_mutex], 0
135
; ok, continue
135
; ok, continue
136
	mov	esi, [.data]		; esi -> data
136
	mov	esi, [.data]		; esi -> data
137
	mov	ecx, [.length]		; ecx = length
137
	mov	ecx, [.length]		; ecx = length
138
; the signature has been already checked in img.is.png
138
; the signature has been already checked in img.is.png
139
	lodsd
139
	lodsd
140
	lodsd
140
	lodsd
141
	sub	ecx, 8
141
	sub	ecx, 8
142
	xor	ebx, ebx	; no image allocated
142
	xor	ebx, ebx	; no image allocated
143
.chunks_loop:
143
.chunks_loop:
144
	sub	ecx, 12
144
	sub	ecx, 12
145
	jc	.eof
145
	jc	.eof
146
	lodsd	; chunk length
146
	lodsd	; chunk length
147
	bswap	eax
147
	bswap	eax
148
	sub	ecx, eax
148
	sub	ecx, eax
149
	jc	.eof
149
	jc	.eof
150
	push	ecx	; save length of data rest
150
	push	ecx	; save length of data rest
151
	xchg	eax, ecx	; ecx = size of data in the chunk
151
	xchg	eax, ecx	; ecx = size of data in the chunk
152
	lodsd	; chunk type
152
	lodsd	; chunk type
153
	cmp	eax, 'IHDR'
153
	cmp	eax, 'IHDR'
154
	jz	.ihdr
154
	jz	.ihdr
155
	cmp	eax, 'IDAT'
155
	cmp	eax, 'IDAT'
156
	jz	.idat
156
	jz	.idat
157
	cmp	eax, 'IEND'
157
	cmp	eax, 'IEND'
158
	jz	.iend
158
	jz	.iend
159
	cmp	eax, 'PLTE'
159
	cmp	eax, 'PLTE'
160
	jz	.palette
160
	jz	.palette
161
; unrecognized chunk, ignore
161
; unrecognized chunk, ignore
162
	lea	esi, [esi+ecx+4]
162
	lea	esi, [esi+ecx+4]
163
	pop	ecx
163
	pop	ecx
164
	jmp	.chunks_loop
164
	jmp	.chunks_loop
165
; IHDR chunk
165
; IHDR chunk
166
.ihdr:
166
.ihdr:
167
	cmp	ecx, 13
167
	cmp	ecx, 13
168
	jnz	.invalid_chunk
168
	jnz	.invalid_chunk
169
	cmp	[.image], 0
169
	cmp	[.image], 0
170
	jnz	.invalid_chunk
170
	jnz	.invalid_chunk
171
; read image characteristics
171
; read image characteristics
172
	lodsd
172
	lodsd
173
	bswap	eax
173
	bswap	eax
174
	mov	[.width], eax
174
	mov	[.width], eax
175
	lodsd
175
	lodsd
176
	bswap	eax
176
	bswap	eax
177
	mov	[.height], eax
177
	mov	[.height], eax
178
	xor	eax, eax
178
	xor	eax, eax
179
	lea	ebx, [eax+1]
179
	lea	ebx, [eax+1]
180
	lodsb
180
	lodsb
181
	cmp	al, 16
181
	cmp	al, 16
182
	ja	.invalid_chunk
182
	ja	.invalid_chunk
183
	test	al, al
183
	test	al, al
184
	jz	.invalid_chunk
184
	jz	.invalid_chunk
185
	lea	edx, [eax-1]
185
	lea	edx, [eax-1]
186
	test	al, dl
186
	test	al, dl
187
	jnz	.invalid_chunk
187
	jnz	.invalid_chunk
188
	mov	[.bit_depth], eax
188
	mov	[.bit_depth], eax
189
	lodsb
189
	lodsb
190
	test	al, not 7
190
	test	al, not 7
191
	jnz	.invalid_chunk
191
	jnz	.invalid_chunk
192
	mov	[.color_type], eax
192
	mov	[.color_type], eax
193
	lodsb
193
	lodsb
194
	test	al, al
194
	test	al, al
195
	jnz	.invalid_chunk	; only compression method 0 is defined
195
	jnz	.invalid_chunk	; only compression method 0 is defined
196
	lodsb
196
	lodsb
197
	test	al, al
197
	test	al, al
198
	jnz	.invalid_chunk	; only filtering method 0 is defined
198
	jnz	.invalid_chunk	; only filtering method 0 is defined
199
	lodsb
199
	lodsb
200
	cmp	al, 1
200
	cmp	al, 1
201
	ja	.invalid_chunk	; only interlacing methods 0 and 1 are defined
201
	ja	.invalid_chunk	; only interlacing methods 0 and 1 are defined
202
	mov	[.interlace], al
202
	mov	[.interlace], al
203
; check for correctness and calculate bytes_per_pixel and scanline_len
203
; check for correctness and calculate bytes_per_pixel and scanline_len
204
	mov	eax, [.bit_depth]
204
	mov	eax, [.bit_depth]
205
	mov	edx, [.color_type]
205
	mov	edx, [.color_type]
206
	dec	edx
206
	dec	edx
207
	js	.grayscale1
207
	js	.grayscale1
208
	dec	edx
208
	dec	edx
209
	jz	.rgb1
209
	jz	.rgb1
210
	dec	edx
210
	dec	edx
211
	jz	.palette1
211
	jz	.palette1
212
	dec	edx
212
	dec	edx
213
	jz	.grayscale_alpha1
213
	jz	.grayscale_alpha1
214
	dec	edx
214
	dec	edx
215
	dec	edx
215
	dec	edx
216
	jnz	.invalid_chunk
216
	jnz	.invalid_chunk
217
.rgb_alpha1:
217
.rgb_alpha1:
218
	inc	ebx
218
	inc	ebx
219
.rgb1:
219
.rgb1:
220
	inc	ebx
220
	inc	ebx
221
.grayscale_alpha1:
221
.grayscale_alpha1:
222
	inc	ebx
222
	inc	ebx
223
	cmp	al, 8
223
	cmp	al, 8
224
	jb	.invalid_chunk
224
	jb	.invalid_chunk
225
	jmp	@f
225
	jmp	@f
226
.palette1:
226
.palette1:
227
	cmp	al, 8
227
	cmp	al, 8
228
	ja	.invalid_chunk
228
	ja	.invalid_chunk
229
.grayscale1:
229
.grayscale1:
230
@@:
230
@@:
231
	mul	ebx
231
	mul	ebx
232
	mov	[.bits_per_pixel], eax
232
	mov	[.bits_per_pixel], eax
233
	add	eax, 7
233
	add	eax, 7
234
	shr	eax, 3
234
	shr	eax, 3
235
	mov	[.bytes_per_pixel], eax
235
	mov	[.bytes_per_pixel], eax
236
; allocate image
236
; allocate image
237
	push	Image.bpp24
237
	push	Image.bpp24
238
	pop	eax
238
	pop	eax
239
	cmp	[.color_type], 2
239
	cmp	[.color_type], 2
240
	jz	@f
240
	jz	@f
241
	mov	al, Image.bpp32
241
	mov	al, Image.bpp32
242
	cmp	[.color_type], 6
242
	cmp	[.color_type], 6
243
	jz	@f
243
	jz	@f
244
	mov	al, Image.bpp8i
244
	mov	al, Image.bpp8i
245
@@:
245
@@:
246
	stdcall	img.create, [.width], [.height], eax
246
	stdcall	img.create, [.width], [.height], eax
247
	test	eax, eax
247
	test	eax, eax
248
	jz	.invalid_chunk
248
	jz	.invalid_chunk
249
	mov	[.image], eax
249
	mov	[.image], eax
250
	jmp	.next_chunk
250
	jmp	.next_chunk
251
.invalid_chunk:
251
.invalid_chunk:
252
.iend:
252
.iend:
253
	pop	ecx
253
	pop	ecx
254
.eof:
254
.eof:
255
	add	esp, .localsize
255
	add	esp, .localsize
256
	popad
256
	popad
257
	ret	12
257
	ret	12
258
; PLTE chunk
258
; PLTE chunk
259
.palette:
259
.palette:
260
	mov	eax, [.image]
260
	mov	eax, [.image]
261
	test	eax, eax
261
	test	eax, eax
262
	jz	.invalid_chunk
262
	jz	.invalid_chunk
263
	cmp	[.color_type], 3
263
	cmp	[.color_type], 3
264
	jz	.copy_palette
264
	jz	.copy_palette
265
.ignore_chunk:
265
.ignore_chunk:
266
	add	esi, ecx
266
	add	esi, ecx
267
.next_chunk:
267
.next_chunk:
268
	lodsd
268
	lodsd
269
	pop	ecx
269
	pop	ecx
270
	jmp	.chunks_loop
270
	jmp	.chunks_loop
271
.copy_palette:
271
.copy_palette:
272
	mov	edi, [eax + Image.Palette]
272
	mov	edi, [eax + Image.Palette]
273
	xor	eax, eax
273
	xor	eax, eax
274
	cmp	ecx, 256*3
274
	cmp	ecx, 256*3
275
	ja	.next_chunk
275
	ja	.next_chunk
276
@@:
276
@@:
277
	sub	ecx, 3
277
	sub	ecx, 3
278
	jz	@f
278
	jz	@f
279
	js	.invalid_chunk
279
	js	.invalid_chunk
280
	lodsd
280
	lodsd
281
	dec	esi
281
	dec	esi
282
	bswap	eax
282
	bswap	eax
283
	shr	eax, 8
283
	shr	eax, 8
284
	stosd
284
	stosd
285
	jmp	@b
285
	jmp	@b
286
@@:
286
@@:
287
	lodsd
287
	lodsd
288
	dec	esi
288
	dec	esi
289
	bswap	eax
289
	bswap	eax
290
	shr	eax, 8
290
	shr	eax, 8
291
	stosd
291
	stosd
292
	jmp	.next_chunk
292
	jmp	.next_chunk
293
.idat:
293
.idat:
294
	jecxz	.next_chunk
294
	jecxz	.next_chunk
295
	cmp	[.idat_read], 0
295
	cmp	[.idat_read], 0
296
	jnz	@f
296
	jnz	@f
297
	lodsb
297
	lodsb
298
	inc	[.idat_read]
298
	inc	[.idat_read]
299
	and	al, 0xF
299
	and	al, 0xF
300
	cmp	al, 8
300
	cmp	al, 8
301
	jnz	.invalid_chunk
301
	jnz	.invalid_chunk
302
	dec	ecx
302
	dec	ecx
303
	jz	.next_chunk
303
	jz	.next_chunk
304
@@:
304
@@:
305
	cmp	[.idat_read], 1
305
	cmp	[.idat_read], 1
306
	jnz	@f
306
	jnz	@f
307
	lodsb
307
	lodsb
308
	inc	[.idat_read]
308
	inc	[.idat_read]
309
	test	al, 20h
309
	test	al, 20h
310
	jnz	.invalid_chunk
310
	jnz	.invalid_chunk
311
	dec	ecx
311
	dec	ecx
312
	jz	.next_chunk
312
	jz	.next_chunk
313
@@:
313
@@:
314
	mov	[.cur_chunk_ptr], esi
314
	mov	[.cur_chunk_ptr], esi
315
	mov	[.cur_chunk_size], ecx
315
	mov	[.cur_chunk_size], ecx
316
	pop	[.length]
316
	pop	[.length]
317
	push	eax
317
	push	eax
318
	push	esp
318
	push	esp
319
	push	ebp
319
	push	ebp
320
	push	.deflate_callback
320
	push	.deflate_callback
321
	call	[deflate_unpack2]
321
	call	[deflate_unpack2]
322
	pop	ecx
322
	pop	ecx
323
	test	eax, eax
323
	test	eax, eax
324
	jz	.invalid_chunk
324
	jz	.invalid_chunk
325
; convert PNG unpacked data to RAW data
325
; convert PNG unpacked data to RAW data
326
	mov	esi, eax
326
	mov	esi, eax
327
	mov	[.allocated], eax
327
	mov	[.allocated], eax
328
	mov	[.size_rest], ecx
328
	mov	[.size_rest], ecx
329
; unfilter and deinterlace
329
; unfilter and deinterlace
330
; .interlace_pass, .starting_row and .starting_col have been already set to 0
330
; .interlace_pass, .starting_row and .starting_col have been already set to 0
331
; .block_width, .block_height, .col_increment, .row_increment were set
331
; .block_width, .block_height, .col_increment, .row_increment were set
332
; to values for non-interlaced images; correct if necessary
332
; to values for non-interlaced images; correct if necessary
333
	cmp	[.interlace], 0
333
	cmp	[.interlace], 0
334
	jz	.deinterlace_loop
334
	jz	.deinterlace_loop
335
	push	8
335
	push	8
336
	pop	eax
336
	pop	eax
337
	mov	[.row_increment], eax
337
	mov	[.row_increment], eax
338
	mov	[.col_increment], eax
338
	mov	[.col_increment], eax
339
	mov	[.block_height], eax
339
	mov	[.block_height], eax
340
	mov	[.block_width], eax
340
	mov	[.block_width], eax
341
	mov	[.row_increment_shift], 3
341
	mov	[.row_increment_shift], 3
342
	mov	[.col_increment_shift], 3
342
	mov	[.col_increment_shift], 3
343
.deinterlace_loop:
343
.deinterlace_loop:
344
	mov	edx, [.height]
344
	mov	edx, [.height]
345
	cmp	edx, [.starting_row]
345
	cmp	edx, [.starting_row]
346
	jbe	.deinterlace_next
346
	jbe	.deinterlace_next
347
	mov	ebx, [.width]
347
	mov	ebx, [.width]
348
	sub	ebx, [.starting_col]
348
	sub	ebx, [.starting_col]
349
	jbe	.deinterlace_next
349
	jbe	.deinterlace_next
350
	mov	cl, [.col_increment_shift]
350
	mov	cl, [.col_increment_shift]
351
	add	ebx, [.col_increment]
351
	add	ebx, [.col_increment]
352
	dec	ebx
352
	dec	ebx
353
	shr	ebx, cl
353
	shr	ebx, cl
354
	mov	eax, [.bits_per_pixel]
354
	mov	eax, [.bits_per_pixel]
355
	imul	eax, ebx
355
	imul	eax, ebx
356
	add	eax, 7
356
	add	eax, 7
357
	shr	eax, 3
357
	shr	eax, 3
358
	mov	[.scanline_len], eax
358
	mov	[.scanline_len], eax
359
	shl	ebx, cl
359
	shl	ebx, cl
360
	mov	[.col_distance], ebx
360
	mov	[.col_distance], ebx
361
; Unfilter
361
; Unfilter
362
	mov	ecx, [.size_rest]
362
	mov	ecx, [.size_rest]
363
	push	esi
363
	push	esi
364
.unfilter_loop_e:
364
.unfilter_loop_e:
365
	mov	ebx, [.scanline_len]
365
	mov	ebx, [.scanline_len]
366
	sub	ecx, 1
366
	sub	ecx, 1
367
	jc	.unfilter_abort
367
	jc	.unfilter_abort
368
	sub	ecx, ebx
368
	sub	ecx, ebx
369
	jc	.unfilter_abort
369
	jc	.unfilter_abort
370
	movzx	eax, byte [esi]
370
	movzx	eax, byte [esi]
371
	add	esi, 1
371
	add	esi, 1
372
	cmp	eax, 4
372
	cmp	eax, 4
373
	ja	.next_scanline
373
	ja	.next_scanline
374
	jmp	dword [@f + eax*4]
374
	jmp	dword [@f + eax*4]
375
align 4
375
align 4
376
@@:
376
@@:
377
	dd	.unfilter_none
377
	dd	.unfilter_none
378
	dd	.unfilter_sub
378
	dd	.unfilter_sub
379
	dd	.unfilter_up
379
	dd	.unfilter_up
380
	dd	.unfilter_average
380
	dd	.unfilter_average
381
	dd	.unfilter_paeth
381
	dd	.unfilter_paeth
382
.unfilter_sub:
382
.unfilter_sub:
383
	mov	edi, [.bytes_per_pixel]
383
	mov	edi, [.bytes_per_pixel]
384
	add	esi, edi
384
	add	esi, edi
385
	sub	ebx, edi
385
	sub	ebx, edi
386
	jbe	.next_scanline
386
	jbe	.next_scanline
387
	neg	edi
387
	neg	edi
388
@@:
388
@@:
389
	mov	al, [esi+edi]
389
	mov	al, [esi+edi]
390
	add	[esi], al
390
	add	[esi], al
391
	add	esi, 1
391
	add	esi, 1
392
	sub	ebx, 1
392
	sub	ebx, 1
393
	jnz	@b
393
	jnz	@b
394
	jmp	.next_scanline
394
	jmp	.next_scanline
395
.unfilter_up:
395
.unfilter_up:
396
	cmp	edx, [.height]
396
	cmp	edx, [.height]
397
	jz	.unfilter_none
397
	jz	.unfilter_none
398
	lea	edi, [ebx+1]
398
	lea	edi, [ebx+1]
399
	neg	edi
399
	neg	edi
400
@@:
400
@@:
401
	mov	al, [esi+edi]
401
	mov	al, [esi+edi]
402
	add	[esi], al
402
	add	[esi], al
403
	add	esi, 1
403
	add	esi, 1
404
	sub	ebx, 1
404
	sub	ebx, 1
405
	jnz	@b
405
	jnz	@b
406
	jmp	.next_scanline
406
	jmp	.next_scanline
407
.unfilter_average:
407
.unfilter_average:
408
	mov	edi, [.bytes_per_pixel]
408
	mov	edi, [.bytes_per_pixel]
409
	cmp	edx, [.height]
409
	cmp	edx, [.height]
410
	jz	.unfilter_average_firstline
410
	jz	.unfilter_average_firstline
411
	push	edx
411
	push	edx
412
	lea	edx, [ebx+1]
412
	lea	edx, [ebx+1]
413
	neg	edx
413
	neg	edx
414
	sub	ebx, edi
414
	sub	ebx, edi
415
@@:
415
@@:
416
	mov	al, [esi+edx]
416
	mov	al, [esi+edx]
417
	shr	al, 1
417
	shr	al, 1
418
	add	[esi], al
418
	add	[esi], al
419
	add	esi, 1
419
	add	esi, 1
420
	sub	edi, 1
420
	sub	edi, 1
421
	jnz	@b
421
	jnz	@b
422
	mov	edi, [.bytes_per_pixel]
422
	mov	edi, [.bytes_per_pixel]
423
	neg	edi
423
	neg	edi
424
	test	ebx, ebx
424
	test	ebx, ebx
425
	jz	.unfilter_average_done
425
	jz	.unfilter_average_done
426
@@:
426
@@:
427
	mov	al, [esi+edx]
427
	mov	al, [esi+edx]
428
	add	al, [esi+edi]
428
	add	al, [esi+edi]
429
	rcr	al, 1
429
	rcr	al, 1
430
	add	[esi], al
430
	add	[esi], al
431
	add	esi, 1
431
	add	esi, 1
432
	sub	ebx, 1
432
	sub	ebx, 1
433
	jnz	@b
433
	jnz	@b
434
.unfilter_average_done:
434
.unfilter_average_done:
435
	pop	edx
435
	pop	edx
436
	jmp	.next_scanline
436
	jmp	.next_scanline
437
.unfilter_average_firstline:
437
.unfilter_average_firstline:
438
	mov	edi, [.bytes_per_pixel]
438
	mov	edi, [.bytes_per_pixel]
439
	add	esi, edi
439
	add	esi, edi
440
	sub	ebx, edi
440
	sub	ebx, edi
441
	jbe	.next_scanline
441
	jbe	.next_scanline
442
	neg	edi
442
	neg	edi
443
@@:
443
@@:
444
	mov	al, [esi+edi]
444
	mov	al, [esi+edi]
445
	shr	al, 1
445
	shr	al, 1
446
	add	[esi], al
446
	add	[esi], al
447
	add	esi, 1
447
	add	esi, 1
448
	sub	ebx, 1
448
	sub	ebx, 1
449
	jnz	@b
449
	jnz	@b
450
	jmp	.unfilter_none
450
	jmp	.unfilter_none
451
.unfilter_paeth:
451
.unfilter_paeth:
452
	cmp	edx, [.height]
452
	cmp	edx, [.height]
453
	jz	.unfilter_sub
453
	jz	.unfilter_sub
454
	push	edx
454
	push	edx
455
	lea	edx, [ebx+1]
455
	lea	edx, [ebx+1]
456
	mov	edi, [.bytes_per_pixel]
456
	mov	edi, [.bytes_per_pixel]
457
	neg	edx
457
	neg	edx
458
	sub	ebx, edi
458
	sub	ebx, edi
459
@@:
459
@@:
460
	mov	al, [esi+edx]
460
	mov	al, [esi+edx]
461
	add	[esi], al
461
	add	[esi], al
462
	add	esi, 1
462
	add	esi, 1
463
	sub	edi, 1
463
	sub	edi, 1
464
	jnz	@b
464
	jnz	@b
465
	mov	edi, [.bytes_per_pixel]
465
	mov	edi, [.bytes_per_pixel]
466
	neg	edi
466
	neg	edi
467
	test	ebx, ebx
467
	test	ebx, ebx
468
	jz	.unfilter_paeth_done
468
	jz	.unfilter_paeth_done
469
	push	ecx
469
	push	ecx
470
@@:
470
@@:
471
	push	ebx
471
	push	ebx
472
; PaethPredictor(Raw(x-bpp) = a, Prior(x) = b, Prior(x-bpp) = c)
472
; PaethPredictor(Raw(x-bpp) = a, Prior(x) = b, Prior(x-bpp) = c)
473
	movzx	eax, byte [esi+edi]
473
	movzx	eax, byte [esi+edi]
474
	mov	[.paeth_a], eax
474
	mov	[.paeth_a], eax
475
	movzx	ecx, byte [esi+edx]
475
	movzx	ecx, byte [esi+edx]
476
	add	edi, edx
476
	add	edi, edx
477
	mov	[.paeth_b], ecx
477
	mov	[.paeth_b], ecx
478
	add	ecx, eax
478
	add	ecx, eax
479
	movzx	eax, byte [esi+edi]
479
	movzx	eax, byte [esi+edi]
480
	mov	[.paeth_c], eax
480
	mov	[.paeth_c], eax
481
	sub	ecx, eax	; ecx = a + b - c = p
481
	sub	ecx, eax	; ecx = a + b - c = p
482
; calculate pa = abs(p-a), pb = abs(p-b), pc = abs(p-c)
482
; calculate pa = abs(p-a), pb = abs(p-b), pc = abs(p-c)
483
	mov	ebx, ecx
483
	mov	ebx, ecx
484
	sub	ebx, eax	; ebx = p - c
484
	sub	ebx, eax	; ebx = p - c
485
	cmp	ebx, 80000000h
485
	cmp	ebx, 80000000h
486
	sbb	eax, eax	; eax = (p < c) ? 0 : 0xFFFFFFF
486
	sbb	eax, eax	; eax = (p < c) ? 0 : 0xFFFFFFF
487
	not	eax		; eax = (p < c) ? 0xFFFFFFFF : 0
487
	not	eax		; eax = (p < c) ? 0xFFFFFFFF : 0
488
	and	eax, ebx	; eax = (p < c) ? p - c : 0
488
	and	eax, ebx	; eax = (p < c) ? p - c : 0
489
	sub	ebx, eax
489
	sub	ebx, eax
490
	sub	ebx, eax	; ebx = abs(p-c)
490
	sub	ebx, eax	; ebx = abs(p-c)
491
	mov	[.paeth_pc], ebx
491
	mov	[.paeth_pc], ebx
492
	mov	ebx, ecx
492
	mov	ebx, ecx
493
	sub	ebx, [.paeth_a]
493
	sub	ebx, [.paeth_a]
494
	cmp	ebx, 80000000h
494
	cmp	ebx, 80000000h
495
	sbb	eax, eax
495
	sbb	eax, eax
496
	not	eax
496
	not	eax
497
	and	eax, ebx
497
	and	eax, ebx
498
	sub	ebx, eax
498
	sub	ebx, eax
499
	sub	ebx, eax
499
	sub	ebx, eax
500
	mov	[.paeth_pa], ebx
500
	mov	[.paeth_pa], ebx
501
	mov	ebx, ecx
501
	mov	ebx, ecx
502
	sub	ebx, [.paeth_b]
502
	sub	ebx, [.paeth_b]
503
	cmp	ebx, 80000000h
503
	cmp	ebx, 80000000h
504
	sbb	eax, eax
504
	sbb	eax, eax
505
	not	eax
505
	not	eax
506
	and	eax, ebx
506
	and	eax, ebx
507
	sub	ebx, eax
507
	sub	ebx, eax
508
	sub	ebx, eax
508
	sub	ebx, eax
509
	;mov	[.paeth_pb], ebx
509
	;mov	[.paeth_pb], ebx
510
; select closest value
510
; select closest value
511
	push	edx
511
	push	edx
512
	mov	edx, [.paeth_b]
512
	mov	edx, [.paeth_b]
513
	sub	edx, [.paeth_a]
513
	sub	edx, [.paeth_a]
514
	sub	ebx, [.paeth_pa]
514
	sub	ebx, [.paeth_pa]
515
	sbb	ecx, ecx	; ecx = (pa > pb) ? 0xFFFFFFFF : 0
515
	sbb	ecx, ecx	; ecx = (pa > pb) ? 0xFFFFFFFF : 0
516
	sbb	eax, eax	; eax = (pa > pb) ? 0xFFFFFFFF : 0
516
	sbb	eax, eax	; eax = (pa > pb) ? 0xFFFFFFFF : 0
517
	and	ecx, ebx	; ecx = (pa > pb) ? pb - pa : 0
517
	and	ecx, ebx	; ecx = (pa > pb) ? pb - pa : 0
518
	and	eax, edx	; eax = (pa > pb) ? b - a : 0
518
	and	eax, edx	; eax = (pa > pb) ? b - a : 0
519
	add	ecx, [.paeth_pa]	; ecx = (pa > pb) ? pb : pa = min(pa,pb)
519
	add	ecx, [.paeth_pa]	; ecx = (pa > pb) ? pb : pa = min(pa,pb)
520
	add	eax, [.paeth_a]		; eax = (pa > pb) ? b : a
520
	add	eax, [.paeth_a]		; eax = (pa > pb) ? b : a
521
	mov	edx, [.paeth_c]
521
	mov	edx, [.paeth_c]
522
	sub	edx, eax
522
	sub	edx, eax
523
	sub	[.paeth_pc], ecx
523
	sub	[.paeth_pc], ecx
524
	sbb	ebx, ebx	; ebx = (min(pa,pb) <= pc) ? 0 : 0xFFFFFFFF
524
	sbb	ebx, ebx	; ebx = (min(pa,pb) <= pc) ? 0 : 0xFFFFFFFF
525
	and	ebx, edx	; ebx = (min(pa,pb) <= pc) ? 0 : c - eax
525
	and	ebx, edx	; ebx = (min(pa,pb) <= pc) ? 0 : c - eax
526
	add	eax, ebx
526
	add	eax, ebx
527
	pop	edx
527
	pop	edx
528
	add	[esi], al
528
	add	[esi], al
529
	pop	ebx
529
	pop	ebx
530
	sub	edi, edx
530
	sub	edi, edx
531
	add	esi, 1
531
	add	esi, 1
532
	sub	ebx, 1
532
	sub	ebx, 1
533
	jnz	@b
533
	jnz	@b
534
	pop	ecx
534
	pop	ecx
535
.unfilter_paeth_done:
535
.unfilter_paeth_done:
536
	pop	edx
536
	pop	edx
537
	jmp	.next_scanline
537
	jmp	.next_scanline
538
.unfilter_none:
538
.unfilter_none:
539
	add	esi, ebx
539
	add	esi, ebx
540
.next_scanline:
540
.next_scanline:
541
	sub	edx, [.row_increment]
541
	sub	edx, [.row_increment]
542
	jc	.unfilter_done
542
	jc	.unfilter_done
543
	cmp	edx, [.starting_row]
543
	cmp	edx, [.starting_row]
544
	jbe	.unfilter_done
544
	jbe	.unfilter_done
545
	jmp	.unfilter_loop_e
545
	jmp	.unfilter_loop_e
546
.unfilter_abort:
546
.unfilter_abort:
547
	xor	ecx, ecx
547
	xor	ecx, ecx
548
.unfilter_done:
548
.unfilter_done:
549
; unfiltering done, now convert to raw data
549
; unfiltering done, now convert to raw data
550
; with deinterlacing if needed
550
; with deinterlacing if needed
551
	pop	esi
551
	pop	esi
552
	mov	ebx, [.image]
552
	mov	ebx, [.image]
553
	mov	eax, [.width]
553
	mov	eax, [.width]
554
	call	img._.get_scanline_len
554
	call	img._.get_scanline_len
555
	mov	[.row_distance], eax
555
	mov	[.row_distance], eax
556
	mov	eax, [.row_increment]
556
	mov	eax, [.row_increment]
557
	mul	[.width]
557
	mul	[.width]
558
	sub	eax, [.col_distance]
558
	sub	eax, [.col_distance]
559
	call	img._.get_scanline_len
559
	call	img._.get_scanline_len
560
	mov	[.col_distance], eax
560
	mov	[.col_distance], eax
561
	mov	edi, [ebx + Image.Data]
561
	mov	edi, [ebx + Image.Data]
562
	mov	eax, [.starting_row]
562
	mov	eax, [.starting_row]
563
	mul	[.width]
563
	mul	[.width]
564
	add	eax, [.starting_col]
564
	add	eax, [.starting_col]
565
	call	img._.get_scanline_len
565
	call	img._.get_scanline_len
566
	add	edi, eax
566
	add	edi, eax
567
	mov	eax, ebx
567
	mov	eax, ebx
568
	mov	ebx, [.size_rest]
568
	mov	ebx, [.size_rest]
569
	mov	[.size_rest], ecx
569
	mov	[.size_rest], ecx
570
	mov	edx, [.height]
570
	mov	edx, [.height]
571
	sub	edx, [.starting_row]
571
	sub	edx, [.starting_row]
572
	mov	[.j], edx
572
	mov	[.j], edx
573
	cmp	[.color_type], 0
573
	cmp	[.color_type], 0
574
	jz	.grayscale2
574
	jz	.grayscale2
575
	cmp	[.color_type], 2
575
	cmp	[.color_type], 2
576
	jz	.rgb2
576
	jz	.rgb2
577
	cmp	[.color_type], 3
577
	cmp	[.color_type], 3
578
	jz	.palette2
578
	jz	.palette2
579
	cmp	[.color_type], 4
579
	cmp	[.color_type], 4
580
	jz	.grayscale_alpha2
580
	jz	.grayscale_alpha2
581
.rgb_alpha2:
581
.rgb_alpha2:
582
	cmp	[.bit_depth], 16
582
	cmp	[.bit_depth], 16
583
	jz	.rgb_alpha2_16bit
583
	jz	.rgb_alpha2_16bit
584
.rgb_alpha2.next:
584
.rgb_alpha2.next:
585
	sub	ebx, 1
585
	sub	ebx, 1
586
	jc	.convert_done
586
	jc	.convert_done
587
	add	esi, 1
587
	add	esi, 1
588
	sub	ebx, [.scanline_len]
588
	sub	ebx, [.scanline_len]
589
	jc	.convert_done
589
	jc	.convert_done
590
	mov	ecx, [.width]
590
	mov	ecx, [.width]
591
	sub	ecx, [.starting_col]
591
	sub	ecx, [.starting_col]
592
	mov	[.i], ecx
592
	mov	[.i], ecx
593
.rgb_alpha2.extloop:
593
.rgb_alpha2.extloop:
594
 
594
 
595
macro init_block
595
macro init_block
596
{
596
{
597
	push	ebx
597
	push	ebx
598
	mov	eax, [.col_increment]
598
	mov	eax, [.col_increment]
599
	mov	edx, [.j]
599
	mov	edx, [.j]
600
	cmp	edx, [.block_height]
600
	cmp	edx, [.block_height]
601
	jb	@f
601
	jb	@f
602
	mov	edx, [.block_height]
602
	mov	edx, [.block_height]
603
@@:
603
@@:
604
	mov	ebx, [.i]
604
	mov	ebx, [.i]
605
	cmp	ebx, [.block_width]
605
	cmp	ebx, [.block_width]
606
	jb	@f
606
	jb	@f
607
	mov	ebx, [.block_width]
607
	mov	ebx, [.block_width]
608
@@:
608
@@:
609
}
609
}
610
 
610
 
611
	init_block
611
	init_block
612
	lea	eax, [edi+eax*4]
612
	lea	eax, [edi+eax*4]
613
	push	eax
613
	push	eax
614
.rgb_alpha2.innloop1:
614
.rgb_alpha2.innloop1:
615
	push	edi
615
	push	edi
616
	mov	ecx, ebx
616
	mov	ecx, ebx
617
.rgb_alpha2.innloop2:
617
.rgb_alpha2.innloop2:
618
	mov	al, [esi+2]
618
	mov	al, [esi+2]
619
	mov	[edi], al
619
	mov	[edi], al
620
	mov	al, [esi+1]
620
	mov	al, [esi+1]
621
	mov	[edi+1], al
621
	mov	[edi+1], al
622
	mov	al, [esi]
622
	mov	al, [esi]
623
	mov	[edi+2], al
623
	mov	[edi+2], al
624
	mov	al, [esi+3]
624
	mov	al, [esi+3]
625
	mov	[edi+3], al
625
	mov	[edi+3], al
626
	add	edi, 4
626
	add	edi, 4
627
	dec	ecx
627
	dec	ecx
628
	jnz	.rgb_alpha2.innloop2
628
	jnz	.rgb_alpha2.innloop2
629
	pop	edi
629
	pop	edi
630
	add	edi, [.row_distance]
630
	add	edi, [.row_distance]
631
	dec	edx
631
	dec	edx
632
	jnz	.rgb_alpha2.innloop1
632
	jnz	.rgb_alpha2.innloop1
633
	pop	edi ebx
633
	pop	edi ebx
634
	add	esi, 4
634
	add	esi, 4
635
	mov	eax, [.col_increment]
635
	mov	eax, [.col_increment]
636
	sub	[.i], eax
636
	sub	[.i], eax
637
	ja	.rgb_alpha2.extloop
637
	ja	.rgb_alpha2.extloop
638
	add	edi, [.col_distance]
638
	add	edi, [.col_distance]
639
	mov	eax, [.row_increment]
639
	mov	eax, [.row_increment]
640
	sub	[.j], eax
640
	sub	[.j], eax
641
	ja	.rgb_alpha2.next
641
	ja	.rgb_alpha2.next
642
	jmp	.convert_done
642
	jmp	.convert_done
643
.rgb_alpha2_16bit:
643
.rgb_alpha2_16bit:
644
	sub	ebx, 1
644
	sub	ebx, 1
645
	jc	.convert_done
645
	jc	.convert_done
646
	add	esi, 1
646
	add	esi, 1
647
	sub	ebx, [.scanline_len]
647
	sub	ebx, [.scanline_len]
648
	jc	.convert_done
648
	jc	.convert_done
649
	mov	ecx, [.width]
649
	mov	ecx, [.width]
650
	sub	ecx, [.starting_col]
650
	sub	ecx, [.starting_col]
651
	mov	[.i], ecx
651
	mov	[.i], ecx
652
.rgb_alpha2_16bit.loop:
652
.rgb_alpha2_16bit.loop:
653
	init_block
653
	init_block
654
	lea	eax, [edi+eax*4]
654
	lea	eax, [edi+eax*4]
655
	push	eax
655
	push	eax
656
 
656
 
657
; convert 16 bit sample to 8 bit sample
657
; convert 16 bit sample to 8 bit sample
658
macro convert_16_to_8
658
macro convert_16_to_8
659
{
659
{
660
local .l1,.l2
660
local .l1,.l2
661
	xor	ah, 0x80
661
	xor	ah, 0x80
662
	js	.l1
662
	js	.l1
663
	cmp	al, ah
663
	cmp	al, ah
664
	adc	al, 0
664
	adc	al, 0
665
	jmp	.l2
665
	jmp	.l2
666
.l1:
666
.l1:
667
	cmp	ah, al
667
	cmp	ah, al
668
	sbb	al, 0
668
	sbb	al, 0
669
.l2:
669
.l2:
670
}
670
}
671
 
671
 
672
.rgb_alpha2_16bit.innloop1:
672
.rgb_alpha2_16bit.innloop1:
673
	push	edi
673
	push	edi
674
	mov	ecx, ebx
674
	mov	ecx, ebx
675
.rgb_alpha2_16bit.innloop2:
675
.rgb_alpha2_16bit.innloop2:
676
	mov	ax, [esi+4]
676
	mov	ax, [esi+4]
677
	convert_16_to_8
677
	convert_16_to_8
678
	mov	[edi], al
678
	mov	[edi], al
679
	mov	ax, [esi+2]
679
	mov	ax, [esi+2]
680
	convert_16_to_8
680
	convert_16_to_8
681
	mov	[edi+1], al
681
	mov	[edi+1], al
682
	mov	ax, [esi]
682
	mov	ax, [esi]
683
	convert_16_to_8
683
	convert_16_to_8
684
	mov	[edi+2], al
684
	mov	[edi+2], al
685
	;mov	ax, [esi+6]
685
	;mov	ax, [esi+6]
686
	;convert_16_to_8
686
	;convert_16_to_8
687
	;mov	[edi+3], al
687
	;mov	[edi+3], al
688
	add	edi, 4
688
	add	edi, 4
689
	dec	ecx
689
	dec	ecx
690
	jnz	.rgb_alpha2_16bit.innloop2
690
	jnz	.rgb_alpha2_16bit.innloop2
691
	pop	edi
691
	pop	edi
692
	add	edi, [.row_distance]
692
	add	edi, [.row_distance]
693
	dec	edx
693
	dec	edx
694
	jnz	.rgb_alpha2_16bit.innloop1
694
	jnz	.rgb_alpha2_16bit.innloop1
695
	pop	edi ebx
695
	pop	edi ebx
696
	add	esi, 8
696
	add	esi, 8
697
	mov	eax, [.col_increment]
697
	mov	eax, [.col_increment]
698
	sub	[.i], eax
698
	sub	[.i], eax
699
	ja	.rgb_alpha2_16bit.loop
699
	ja	.rgb_alpha2_16bit.loop
700
	add	edi, [.col_distance]
700
	add	edi, [.col_distance]
701
	mov	eax, [.row_increment]
701
	mov	eax, [.row_increment]
702
	sub	[.j], eax
702
	sub	[.j], eax
703
	ja	.rgb_alpha2_16bit
703
	ja	.rgb_alpha2_16bit
704
	jmp	.convert_done
704
	jmp	.convert_done
705
.grayscale2:
705
.grayscale2:
706
	call	.create_grayscale_palette
706
	call	.create_grayscale_palette
707
	cmp	[.bit_depth], 16
707
	cmp	[.bit_depth], 16
708
	jz	.grayscale2_16bit
708
	jz	.grayscale2_16bit
709
.palette2:
709
.palette2:
710
	cmp	[.bit_depth], 1
710
	cmp	[.bit_depth], 1
711
	jz	.palette2_1bit
711
	jz	.palette2_1bit
712
	cmp	[.bit_depth], 2
712
	cmp	[.bit_depth], 2
713
	jz	.palette2_2bit
713
	jz	.palette2_2bit
714
	cmp	[.bit_depth], 4
714
	cmp	[.bit_depth], 4
715
	jz	.palette2_4bit
715
	jz	.palette2_4bit
716
.palette2_8bit:
716
.palette2_8bit:
717
	sub	ebx, 1
717
	sub	ebx, 1
718
	jc	.convert_done
718
	jc	.convert_done
719
	add	esi, 1
719
	add	esi, 1
720
	sub	ebx, [.scanline_len]
720
	sub	ebx, [.scanline_len]
721
	jc	.convert_done
721
	jc	.convert_done
722
	mov	ecx, [.width]
722
	mov	ecx, [.width]
723
	sub	ecx, [.starting_col]
723
	sub	ecx, [.starting_col]
724
	mov	[.i], ecx
724
	mov	[.i], ecx
725
.palette2_8bit.extloop:
725
.palette2_8bit.extloop:
726
	init_block
726
	init_block
727
	add	eax, edi
727
	add	eax, edi
728
	push	eax
728
	push	eax
729
	mov	al, [esi]
729
	mov	al, [esi]
730
	inc	esi
730
	inc	esi
731
macro block_byte_innerloop extloop
731
macro block_byte_innerloop extloop
732
{
732
{
733
local .l1
733
local .l1
734
.l1:
734
.l1:
735
	mov	ecx, ebx
735
	mov	ecx, ebx
736
	rep	stosb
736
	rep	stosb
737
	sub	edi, ebx
737
	sub	edi, ebx
738
	add	edi, [.row_distance]
738
	add	edi, [.row_distance]
739
	dec	edx
739
	dec	edx
740
	jnz	.l1
740
	jnz	.l1
741
	pop	edi ebx
741
	pop	edi ebx
742
	mov	eax, [.col_increment]
742
	mov	eax, [.col_increment]
743
	sub	[.i], eax
743
	sub	[.i], eax
744
	ja	extloop
744
	ja	extloop
745
	add	edi, [.col_distance]
745
	add	edi, [.col_distance]
746
	mov	eax, [.row_increment]
746
	mov	eax, [.row_increment]
747
	sub	[.j], eax
747
	sub	[.j], eax
748
}
748
}
749
	block_byte_innerloop .palette2_8bit.extloop
749
	block_byte_innerloop .palette2_8bit.extloop
750
	ja	.palette2_8bit
750
	ja	.palette2_8bit
751
	jmp	.convert_done
751
	jmp	.convert_done
752
.palette2_4bit:
752
.palette2_4bit:
753
	sub	ebx, 1
753
	sub	ebx, 1
754
	jc	.convert_done
754
	jc	.convert_done
755
	add	esi, 1
755
	add	esi, 1
756
	sub	ebx, [.scanline_len]
756
	sub	ebx, [.scanline_len]
757
	jc	.convert_done
757
	jc	.convert_done
758
	mov	ecx, [.width]
758
	mov	ecx, [.width]
759
	sub	ecx, [.starting_col]
759
	sub	ecx, [.starting_col]
760
	mov	[.i], ecx
760
	mov	[.i], ecx
761
	mov	[.shift], 0
761
	mov	[.shift], 0
762
.palette2_4bit.extloop:
762
.palette2_4bit.extloop:
763
	init_block
763
	init_block
764
	add	eax, edi
764
	add	eax, edi
765
	push	eax
765
	push	eax
766
	xor	[.shift], 1
766
	xor	[.shift], 1
767
	jz	.palette2_4bit.shifted
767
	jz	.palette2_4bit.shifted
768
	mov	al, [esi]
768
	mov	al, [esi]
769
	inc	esi
769
	inc	esi
770
	shr	al, 4
770
	shr	al, 4
771
	jmp	@f
771
	jmp	@f
772
.palette2_4bit.shifted:
772
.palette2_4bit.shifted:
773
	mov	al, [esi-1]
773
	mov	al, [esi-1]
774
	and	al, 0xF
774
	and	al, 0xF
775
@@:
775
@@:
776
	block_byte_innerloop .palette2_4bit.extloop
776
	block_byte_innerloop .palette2_4bit.extloop
777
	ja	.palette2_4bit
777
	ja	.palette2_4bit
778
	jmp	.convert_done
778
	jmp	.convert_done
779
.palette2_2bit:
779
.palette2_2bit:
780
	sub	ebx, 1
780
	sub	ebx, 1
781
	jc	.convert_done
781
	jc	.convert_done
782
	add	esi, 1
782
	add	esi, 1
783
	sub	ebx, [.scanline_len]
783
	sub	ebx, [.scanline_len]
784
	jc	.convert_done
784
	jc	.convert_done
785
	mov	ecx, [.width]
785
	mov	ecx, [.width]
786
	sub	ecx, [.starting_col]
786
	sub	ecx, [.starting_col]
787
	mov	[.i], ecx
787
	mov	[.i], ecx
788
	mov	[.shift], 0
788
	mov	[.shift], 0
789
.palette2_2bit.extloop:
789
.palette2_2bit.extloop:
790
	init_block
790
	init_block
791
	add	eax, edi
791
	add	eax, edi
792
	push	eax
792
	push	eax
793
	mov	cl, [.shift]
793
	mov	cl, [.shift]
794
	sub	cl, 2
794
	sub	cl, 2
795
	jns	.palette2_2bit.shifted
795
	jns	.palette2_2bit.shifted
796
	mov	cl, 6
796
	mov	cl, 6
797
	mov	al, [esi]
797
	mov	al, [esi]
798
	inc	esi
798
	inc	esi
799
	shr	al, cl
799
	shr	al, cl
800
	jmp	@f
800
	jmp	@f
801
.palette2_2bit.shifted:
801
.palette2_2bit.shifted:
802
	mov	al, [esi-1]
802
	mov	al, [esi-1]
803
	shr	al, cl
803
	shr	al, cl
804
	and	al, 3
804
	and	al, 3
805
@@:
805
@@:
806
	mov	[.shift], cl
806
	mov	[.shift], cl
807
	block_byte_innerloop .palette2_2bit.extloop
807
	block_byte_innerloop .palette2_2bit.extloop
808
	ja	.palette2_2bit
808
	ja	.palette2_2bit
809
	jmp	.convert_done
809
	jmp	.convert_done
810
.palette2_1bit:
810
.palette2_1bit:
811
	sub	ebx, 1
811
	sub	ebx, 1
812
	jc	.convert_done
812
	jc	.convert_done
813
	add	esi, 1
813
	add	esi, 1
814
	sub	ebx, [.scanline_len]
814
	sub	ebx, [.scanline_len]
815
	jc	.convert_done
815
	jc	.convert_done
816
	mov	ecx, [.width]
816
	mov	ecx, [.width]
817
	sub	ecx, [.starting_col]
817
	sub	ecx, [.starting_col]
818
	mov	[.i], ecx
818
	mov	[.i], ecx
819
	mov	[.shift], 0
819
	mov	[.shift], 0
820
.palette2_1bit.extloop:
820
.palette2_1bit.extloop:
821
	init_block
821
	init_block
822
	add	eax, edi
822
	add	eax, edi
823
	push	eax
823
	push	eax
824
	mov	cl, [.shift]
824
	mov	cl, [.shift]
825
	dec	cl
825
	dec	cl
826
	jns	.palette2_1bit.shifted
826
	jns	.palette2_1bit.shifted
827
	mov	cl, 7
827
	mov	cl, 7
828
	mov	al, [esi]
828
	mov	al, [esi]
829
	inc	esi
829
	inc	esi
830
	shr	al, cl
830
	shr	al, cl
831
	jmp	@f
831
	jmp	@f
832
.palette2_1bit.shifted:
832
.palette2_1bit.shifted:
833
	mov	al, [esi-1]
833
	mov	al, [esi-1]
834
	shr	al, cl
834
	shr	al, cl
835
	and	al, 1
835
	and	al, 1
836
@@:
836
@@:
837
	mov	[.shift], cl
837
	mov	[.shift], cl
838
	block_byte_innerloop .palette2_1bit.extloop
838
	block_byte_innerloop .palette2_1bit.extloop
839
	ja	.palette2_1bit
839
	ja	.palette2_1bit
840
	jmp	.convert_done
840
	jmp	.convert_done
841
.grayscale2_16bit:
841
.grayscale2_16bit:
842
	sub	ebx, 1
842
	sub	ebx, 1
843
	jc	.convert_done
843
	jc	.convert_done
844
	add	esi, 1
844
	add	esi, 1
845
	sub	ebx, [.scanline_len]
845
	sub	ebx, [.scanline_len]
846
	jc	.convert_done
846
	jc	.convert_done
847
	mov	ecx, [.width]
847
	mov	ecx, [.width]
848
	sub	ecx, [.starting_col]
848
	sub	ecx, [.starting_col]
849
	mov	[.i], ecx
849
	mov	[.i], ecx
850
.grayscale2_16bit.extloop:
850
.grayscale2_16bit.extloop:
851
	init_block
851
	init_block
852
	add	eax, edi
852
	add	eax, edi
853
	push	eax
853
	push	eax
854
	mov	ax, [esi]
854
	mov	ax, [esi]
855
	add	esi, 2
855
	add	esi, 2
856
	convert_16_to_8
856
	convert_16_to_8
857
	block_byte_innerloop .grayscale2_16bit.extloop
857
	block_byte_innerloop .grayscale2_16bit.extloop
858
	ja	.grayscale2_16bit
858
	ja	.grayscale2_16bit
859
	jmp	.convert_done
859
	jmp	.convert_done
860
.rgb2:
860
.rgb2:
861
	cmp	[.bit_depth], 16
861
	cmp	[.bit_depth], 16
862
	jz	.rgb2_16bit
862
	jz	.rgb2_16bit
863
.rgb2.next:
863
.rgb2.next:
864
	sub	ebx, 1
864
	sub	ebx, 1
865
	jc	.convert_done
865
	jc	.convert_done
866
	add	esi, 1
866
	add	esi, 1
867
	sub	ebx, [.scanline_len]
867
	sub	ebx, [.scanline_len]
868
	jc	.convert_done
868
	jc	.convert_done
869
	mov	ecx, [.width]
869
	mov	ecx, [.width]
870
	sub	ecx, [.starting_col]
870
	sub	ecx, [.starting_col]
871
	mov	[.i], ecx
871
	mov	[.i], ecx
872
.rgb2.extloop:
872
.rgb2.extloop:
873
	init_block
873
	init_block
874
	lea	eax, [eax*3]
874
	lea	eax, [eax*3]
875
	add	eax, edi
875
	add	eax, edi
876
	push	eax
876
	push	eax
877
.rgb2.innloop1:
877
.rgb2.innloop1:
878
	push	edi
878
	push	edi
879
	mov	ecx, ebx
879
	mov	ecx, ebx
880
.rgb2.innloop2:
880
.rgb2.innloop2:
881
	mov	al, [esi+2]
881
	mov	al, [esi+2]
882
	mov	[edi], al
882
	mov	[edi], al
883
	mov	al, [esi+1]
883
	mov	al, [esi+1]
884
	mov	[edi+1], al
884
	mov	[edi+1], al
885
	mov	al, [esi]
885
	mov	al, [esi]
886
	mov	[edi+2], al
886
	mov	[edi+2], al
887
	add	edi, 3
887
	add	edi, 3
888
	dec	ecx
888
	dec	ecx
889
	jnz	.rgb2.innloop2
889
	jnz	.rgb2.innloop2
890
	pop	edi
890
	pop	edi
891
	add	edi, [.row_distance]
891
	add	edi, [.row_distance]
892
	dec	edx
892
	dec	edx
893
	jnz	.rgb2.innloop1
893
	jnz	.rgb2.innloop1
894
	pop	edi ebx
894
	pop	edi ebx
895
	add	esi, 3
895
	add	esi, 3
896
	mov	eax, [.col_increment]
896
	mov	eax, [.col_increment]
897
	sub	[.i], eax
897
	sub	[.i], eax
898
	ja	.rgb2.extloop
898
	ja	.rgb2.extloop
899
	add	edi, [.col_distance]
899
	add	edi, [.col_distance]
900
	mov	eax, [.row_increment]
900
	mov	eax, [.row_increment]
901
	sub	[.j], eax
901
	sub	[.j], eax
902
	ja	.rgb2.next
902
	ja	.rgb2.next
903
	jmp	.convert_done
903
	jmp	.convert_done
904
.rgb2_16bit:
904
.rgb2_16bit:
905
	sub	ebx, 1
905
	sub	ebx, 1
906
	jc	.convert_done
906
	jc	.convert_done
907
	add	esi, 1
907
	add	esi, 1
908
	sub	ebx, [.scanline_len]
908
	sub	ebx, [.scanline_len]
909
	jc	.convert_done
909
	jc	.convert_done
910
	mov	ecx, [.width]
910
	mov	ecx, [.width]
911
	sub	ecx, [.starting_col]
911
	sub	ecx, [.starting_col]
912
	mov	[.i], ecx
912
	mov	[.i], ecx
913
.rgb2_16bit.extloop:
913
.rgb2_16bit.extloop:
914
	init_block
914
	init_block
915
	lea	eax, [eax*3]
915
	lea	eax, [eax*3]
916
	add	eax, edi
916
	add	eax, edi
917
	push	eax
917
	push	eax
918
.rgb2_16bit.innloop1:
918
.rgb2_16bit.innloop1:
919
	push	edi
919
	push	edi
920
	mov	ecx, ebx
920
	mov	ecx, ebx
921
.rgb2_16bit.innloop2:
921
.rgb2_16bit.innloop2:
922
	mov	ax, [esi+4]
922
	mov	ax, [esi+4]
923
	convert_16_to_8
923
	convert_16_to_8
924
	mov	[edi], al
924
	mov	[edi], al
925
	mov	ax, [esi+2]
925
	mov	ax, [esi+2]
926
	convert_16_to_8
926
	convert_16_to_8
927
	mov	[edi+1], al
927
	mov	[edi+1], al
928
	mov	ax, [esi]
928
	mov	ax, [esi]
929
	convert_16_to_8
929
	convert_16_to_8
930
	mov	[edi+2], al
930
	mov	[edi+2], al
931
	add	edi, 3
931
	add	edi, 3
932
	dec	ecx
932
	dec	ecx
933
	jnz	.rgb2_16bit.innloop2
933
	jnz	.rgb2_16bit.innloop2
934
	pop	edi
934
	pop	edi
935
	add	edi, [.row_distance]
935
	add	edi, [.row_distance]
936
	dec	edx
936
	dec	edx
937
	jnz	.rgb2_16bit.innloop1
937
	jnz	.rgb2_16bit.innloop1
938
	pop	edi ebx
938
	pop	edi ebx
939
	add	esi, 6
939
	add	esi, 6
940
	mov	eax, [.col_increment]
940
	mov	eax, [.col_increment]
941
	sub	[.i], eax
941
	sub	[.i], eax
942
	ja	.rgb2_16bit.extloop
942
	ja	.rgb2_16bit.extloop
943
	add	edi, [.col_distance]
943
	add	edi, [.col_distance]
944
	mov	eax, [.row_increment]
944
	mov	eax, [.row_increment]
945
	sub	[.j], eax
945
	sub	[.j], eax
946
	ja	.rgb2_16bit
946
	ja	.rgb2_16bit
947
	jmp	.convert_done
947
	jmp	.convert_done
948
.grayscale_alpha2:
948
.grayscale_alpha2:
949
	call	.create_grayscale_palette
949
	call	.create_grayscale_palette
950
	cmp	[.bit_depth], 16
950
	cmp	[.bit_depth], 16
951
	jz	.grayscale_alpha2_16bit
951
	jz	.grayscale_alpha2_16bit
952
.grayscale_alpha2.next:
952
.grayscale_alpha2.next:
953
	sub	ebx, 1
953
	sub	ebx, 1
954
	jc	.convert_done
954
	jc	.convert_done
955
	add	esi, 1
955
	add	esi, 1
956
	sub	ebx, [.scanline_len]
956
	sub	ebx, [.scanline_len]
957
	jc	.convert_done
957
	jc	.convert_done
958
	mov	ecx, [.width]
958
	mov	ecx, [.width]
959
	sub	ecx, [.starting_col]
959
	sub	ecx, [.starting_col]
960
	mov	[.i], ecx
960
	mov	[.i], ecx
961
.grayscale_alpha2.extloop:
961
.grayscale_alpha2.extloop:
962
	init_block
962
	init_block
963
	add	eax, edi
963
	add	eax, edi
964
	push	eax
964
	push	eax
965
	mov	al, [esi]
965
	mov	al, [esi]
966
	add	esi, 2
966
	add	esi, 2
967
	block_byte_innerloop .grayscale_alpha2.extloop
967
	block_byte_innerloop .grayscale_alpha2.extloop
968
	ja	.grayscale_alpha2.next
968
	ja	.grayscale_alpha2.next
969
	jmp	.convert_done
969
	jmp	.convert_done
970
.grayscale_alpha2_16bit:
970
.grayscale_alpha2_16bit:
971
	sub	ebx, 1
971
	sub	ebx, 1
972
	jc	.convert_done
972
	jc	.convert_done
973
	add	esi, 1
973
	add	esi, 1
974
	sub	ebx, [.scanline_len]
974
	sub	ebx, [.scanline_len]
975
	jc	.convert_done
975
	jc	.convert_done
976
	mov	ecx, [.width]
976
	mov	ecx, [.width]
977
	sub	ecx, [.starting_col]
977
	sub	ecx, [.starting_col]
978
	mov	[.i], ecx
978
	mov	[.i], ecx
979
.grayscale_alpha2_16bit.extloop:
979
.grayscale_alpha2_16bit.extloop:
980
	init_block
980
	init_block
981
	add	eax, edi
981
	add	eax, edi
982
	push	eax
982
	push	eax
983
	mov	ax, [esi]
983
	mov	ax, [esi]
984
	add	esi, 4
984
	add	esi, 4
985
	convert_16_to_8
985
	convert_16_to_8
986
	block_byte_innerloop .grayscale_alpha2_16bit.extloop
986
	block_byte_innerloop .grayscale_alpha2_16bit.extloop
987
	ja	.grayscale_alpha2_16bit
987
	ja	.grayscale_alpha2_16bit
988
.convert_done:
988
.convert_done:
989
; next interlace pass
989
; next interlace pass
990
.deinterlace_next:
990
.deinterlace_next:
991
	mov	eax, [.block_width]
991
	mov	eax, [.block_width]
992
	cmp	eax, [.block_height]
992
	cmp	eax, [.block_height]
993
	jz	.deinterlace_dec_width
993
	jz	.deinterlace_dec_width
994
	mov	[.block_height], eax
994
	mov	[.block_height], eax
995
	mov	[.col_increment], eax
995
	mov	[.col_increment], eax
996
	dec	[.col_increment_shift]
996
	dec	[.col_increment_shift]
997
	mov	[.starting_row], eax
997
	mov	[.starting_row], eax
998
	and	[.starting_col], 0
998
	and	[.starting_col], 0
999
	jmp	.deinterlace_loop
999
	jmp	.deinterlace_loop
1000
.deinterlace_dec_width:
1000
.deinterlace_dec_width:
1001
	shr	eax, 1
1001
	shr	eax, 1
1002
	jz	.deinterlace_done
1002
	jz	.deinterlace_done
1003
	mov	[.block_width], eax
1003
	mov	[.block_width], eax
1004
	mov	[.starting_col], eax
1004
	mov	[.starting_col], eax
1005
	add	eax, eax
1005
	add	eax, eax
1006
	and	[.starting_row], 0
1006
	and	[.starting_row], 0
1007
	mov	[.row_increment], eax
1007
	mov	[.row_increment], eax
1008
	bsf	eax, eax
1008
	bsf	eax, eax
1009
	mov	[.row_increment_shift], al
1009
	mov	[.row_increment_shift], al
1010
	jmp	.deinterlace_loop
1010
	jmp	.deinterlace_loop
1011
.deinterlace_done:
1011
.deinterlace_done:
1012
	mcall	68, 13, [.allocated]
1012
	mcall	68, 13, [.allocated]
1013
	mov	esi, [.cur_chunk_ptr]
1013
	mov	esi, [.cur_chunk_ptr]
1014
	add	esi, [.cur_chunk_size]
1014
	add	esi, [.cur_chunk_size]
1015
	push	[.length]
1015
	push	[.length]
1016
	jmp	.next_chunk
1016
	jmp	.next_chunk
1017
 
1017
 
1018
.deflate_callback:
1018
.deflate_callback:
1019
	mov	ebp, [esp+4]
1019
	mov	ebp, [esp+4]
1020
	mov	ebx, [esp+8]
1020
	mov	ebx, [esp+8]
1021
	xor	eax, eax
1021
	xor	eax, eax
1022
	mov	esi, [.cur_chunk_size]
1022
	mov	esi, [.cur_chunk_size]
1023
	mov	[ebx], esi
1023
	mov	[ebx], esi
1024
	test	esi, esi
1024
	test	esi, esi
1025
	jz	.deflate_callback.ret
1025
	jz	.deflate_callback.ret
1026
	mov	eax, [.cur_chunk_ptr]
1026
	mov	eax, [.cur_chunk_ptr]
1027
	mov	ecx, [.length]
1027
	mov	ecx, [.length]
1028
	add	esi, eax
1028
	add	esi, eax
1029
	mov	[.cur_chunk_ptr], esi
1029
	mov	[.cur_chunk_ptr], esi
1030
	and	[.cur_chunk_size], 0
1030
	and	[.cur_chunk_size], 0
1031
@@:
1031
@@:
1032
	sub	ecx, 12
1032
	sub	ecx, 12
1033
	jb	.deflate_callback.ret
1033
	jb	.deflate_callback.ret
1034
	cmp	dword [esi+4+4], 'IDAT'
1034
	cmp	dword [esi+4+4], 'IDAT'
1035
	jnz	.deflate_callback.ret
1035
	jnz	.deflate_callback.ret
1036
	mov	edx, [esi+4]
1036
	mov	edx, [esi+4]
1037
	bswap	edx
1037
	bswap	edx
1038
	sub	ecx, edx
1038
	sub	ecx, edx
1039
	jb	.deflate_callback.ret
1039
	jb	.deflate_callback.ret
1040
	add	esi, 4+8
1040
	add	esi, 4+8
1041
	test	edx, edx
1041
	test	edx, edx
1042
	jz	@b
1042
	jz	@b
1043
	mov	[.cur_chunk_size], edx
1043
	mov	[.cur_chunk_size], edx
1044
	mov	[.cur_chunk_ptr], esi
1044
	mov	[.cur_chunk_ptr], esi
1045
	mov	[.length], ecx
1045
	mov	[.length], ecx
1046
.deflate_callback.ret:
1046
.deflate_callback.ret:
1047
	ret	8
1047
	ret	8
1048
 
1048
 
1049
.create_grayscale_palette:
1049
.create_grayscale_palette:
1050
	push	edi edx
1050
	push	edi edx
1051
	mov	edi, [eax + Image.Palette]
1051
	mov	edi, [eax + Image.Palette]
1052
	mov	ecx, [.bit_depth]
1052
	mov	ecx, [.bit_depth]
1053
	cmp	cl, 16
1053
	cmp	cl, 16
1054
	jnz	@f
1054
	jnz	@f
1055
	mov	cl, 8
1055
	mov	cl, 8
1056
@@:
1056
@@:
1057
	push	1
1057
	push	1
1058
	pop	eax
1058
	pop	eax
1059
	shl	eax, cl
1059
	shl	eax, cl
1060
	xchg	eax, ecx
1060
	xchg	eax, ecx
1061
	mov	edx, 0x010101
1061
	mov	edx, 0x010101
1062
	cmp	al, 8
1062
	cmp	al, 8
1063
	jz	.graypal_common
1063
	jz	.graypal_common
1064
	mov	edx, 0x111111
1064
	mov	edx, 0x111111
1065
	cmp	al, 4
1065
	cmp	al, 4
1066
	jz	.graypal_common
1066
	jz	.graypal_common
1067
	mov	edx, 0x555555
1067
	mov	edx, 0x555555
1068
	cmp	al, 2
1068
	cmp	al, 2
1069
	jz	.graypal_common
1069
	jz	.graypal_common
1070
	mov	edx, 0xFFFFFF
1070
	mov	edx, 0xFFFFFF
1071
.graypal_common:
1071
.graypal_common:
1072
	xor	eax, eax
1072
	xor	eax, eax
1073
@@:
1073
@@:
1074
	stosd
1074
	stosd
1075
	add	eax, edx
1075
	add	eax, edx
1076
	loop	@b
1076
	loop	@b
1077
	pop	edx edi
1077
	pop	edx edi
1078
	ret
1078
	ret
1079
;endp
1079
;endp
1080
 
1080
 
1081
 
1081
 
1082
 
1082
 
1083
;;================================================================================================;;
1083
;;================================================================================================;;
1084
align 4
1084
align 4
1085
proc img.encode.png uses ebx edx, _img:dword, _common:dword, _specific:dword
1085
proc img.encode.png uses ebx edx, _img:dword, _common:dword, _specific:dword
1086
;;------------------------------------------------------------------------------------------------;;
1086
;;------------------------------------------------------------------------------------------------;;
1087
;? Encode image into raw data in png format                                                       ;;
1087
;? Encode image into raw data in png format                                                       ;;
1088
;;------------------------------------------------------------------------------------------------;;
1088
;;------------------------------------------------------------------------------------------------;;
1089
;> [_img]      = pointer to image                                                                 ;;
1089
;> [_img]      = pointer to image                                                                 ;;
1090
;> [_common]   = format independent options                                                       ;;
1090
;> [_common]   = format independent options                                                       ;;
1091
;> [_specific] = 0 / pointer to the structure of format specific options                          ;;
1091
;> [_specific] = 0 / pointer to the structure of format specific options                          ;;
1092
;;------------------------------------------------------------------------------------------------;;
1092
;;------------------------------------------------------------------------------------------------;;
1093
;< eax = 0 / pointer to encoded data                                                              ;;
1093
;< eax = 0 / pointer to encoded data                                                              ;;
1094
;< ecx = error code / the size of encoded data                                                    ;;
1094
;< ecx = error code / the size of encoded data                                                    ;;
1095
;;================================================================================================;;
1095
;;================================================================================================;;
1096
locals
1096
locals
1097
	encoded_file rd 1
1097
	encoded_file rd 1
1098
	encoded_file_size rd 1
1098
	encoded_file_size rd 1
1099
	simag png_image
1099
	simag png_image
1100
endl
1100
endl
1101
	mov ebx,[_img]
1101
	mov ebx,[_img]
1102
	mov	eax,[ebx+Image.Type]
1102
	mov	eax,[ebx+Image.Type]
1103
	cmp	eax,Image.bpp24
1103
	cmp	eax,Image.bpp24
1104
	je @f
1104
	je @f
1105
		mov	ecx,LIBIMG_ERROR_BIT_DEPTH
1105
		mov	ecx,LIBIMG_ERROR_BIT_DEPTH
1106
		jmp	.error
1106
		jmp	.error
1107
	@@:
1107
	@@:
1108
 
1108
 
1109
	mov edx,ebp
1109
	mov edx,ebp
1110
	sub edx,sizeof.png_image
1110
	sub edx,sizeof.png_image
1111
	mov dword[edx+png_image.version],PNG_IMAGE_VERSION
1111
	mov dword[edx+png_image.version],PNG_IMAGE_VERSION
1112
	mov ecx,[ebx+Image.Width]
1112
	mov ecx,[ebx+Image.Width]
1113
	mov [edx+png_image.width],ecx ;Image width in pixels (columns)
1113
	mov [edx+png_image.width],ecx ;Image width in pixels (columns)
1114
	mov eax,[ebx+Image.Height]
1114
	mov eax,[ebx+Image.Height]
1115
	mov [edx+png_image.height],eax ;Image height in pixels (rows)
1115
	mov [edx+png_image.height],eax ;Image height in pixels (rows)
1116
	mov dword[edx+png_image.format],PNG_COLOR_TYPE_RGB
1116
	mov dword[edx+png_image.format],PNG_COLOR_TYPE_RGB
1117
	;mov dword[edx+png_image.flags],PNG_IMAGE_FLAG_???
1117
	;mov dword[edx+png_image.flags],PNG_IMAGE_FLAG_???
1118
 
1118
 
1119
	imul ecx,3
1119
	imul ecx,3
1120
	mov edi,ecx
1120
	mov edi,ecx
1121
	imul edi,[ebx+Image.Height]
1121
	imul edi,[ebx+Image.Height]
-
 
1122
	cmp edi,4096
-
 
1123
	jge @f
-
 
1124
		mov edi,4096 ;minimum memory size
-
 
1125
	@@:
1122
	mov [encoded_file_size],edi
1126
	mov [encoded_file_size],edi
1123
	stdcall [mem.alloc],edi
1127
	stdcall [mem.alloc],edi
1124
	test eax,eax
1128
	test eax,eax
1125
	jnz	@f
1129
	jnz	@f
1126
		mov	ecx,LIBIMG_ERROR_OUT_OF_MEMORY
1130
		mov	ecx,LIBIMG_ERROR_OUT_OF_MEMORY
1127
		jmp	.error
1131
		jmp	.error
1128
    @@:
1132
    @@:
1129
	mov [encoded_file],eax
1133
	mov [encoded_file],eax
1130
	mov edi,edx
1134
	mov edi,edx
1131
	sub edi,4
1135
	sub edi,4
1132
	stdcall png_image_write_to_memory, edx,eax,edi,0,[ebx+Image.Data],ecx,0
1136
	stdcall png_image_write_to_memory, edx,eax,edi,0,[ebx+Image.Data],ecx,0
1133
	mov	eax,[encoded_file]
1137
	mov	eax,[encoded_file]
1134
	mov	ecx,[encoded_file_size]
1138
	mov	ecx,[encoded_file_size]
1135
	jmp	.quit
1139
	jmp	.quit
1136
 
1140
 
1137
.error:
1141
.error:
1138
	xor	eax,eax
1142
	xor	eax,eax
1139
.quit:
1143
.quit:
1140
	ret
1144
	ret
1141
endp
1145
endp