Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2388 dunkaist 1
;;================================================================================================;;
3503 dunkaist 2
;;//// tiff.asm //// (c) dunkaist, 2011-2013 /////////////////////////////////////////////////////;;
2388 dunkaist 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
include 'tiff.inc'
21
 
22
;;================================================================================================;;
23
proc img.is.tiff _data, _length ;/////////////////////////////////////////////////////////////////;;
24
;;------------------------------------------------------------------------------------------------;;
25
;? Determine if raw data could be decoded (is in tiff format)                                     ;;
26
;;------------------------------------------------------------------------------------------------;;
27
;> _data = raw data as read from file/stream                                                      ;;
28
;> _length = data length                                                                          ;;
29
;;------------------------------------------------------------------------------------------------;;
30
;< eax = false / true                                                                             ;;
31
;;================================================================================================;;
32
 
33
	push	esi
34
 
35
	mov	esi, [_data]
36
	lodsw
37
	cmp	ax, word 'II'
38
	je	.little_endian
39
	cmp	ax, word 'MM'
40
	je	.big_endian
41
	jmp	.is_not_tiff
42
 
43
  .little_endian:
44
	lodsw
45
	cmp	ax, 0x002A
46
	je	.is_tiff
47
	jmp	.is_not_tiff
48
 
49
  .big_endian:
50
	lodsw
51
	cmp	ax, 0x2A00
52
	je	.is_tiff
53
 
54
  .is_not_tiff:
55
	pop	esi
56
	xor	eax, eax
57
	ret
58
 
59
  .is_tiff:
60
	pop	esi
61
	xor	eax, eax
62
	inc	eax
63
	ret
64
endp
65
 
66
;;================================================================================================;;
67
proc img.decode.tiff _data, _length, _options ;///////////////////////////////////////////////////;;
68
;;------------------------------------------------------------------------------------------------;;
69
;? Decode data into image if it contains correctly formed raw data in tiff format                 ;;
70
;;------------------------------------------------------------------------------------------------;;
71
;> _data = raw data as read from file/stream                                                      ;;
72
;> _length = data length                                                                          ;;
73
;;------------------------------------------------------------------------------------------------;;
74
;< eax = 0 (error) or pointer to image                                                            ;;
75
;;================================================================================================;;
76
locals
77
	_endianness		rd 1		; 0 stands for LE, otherwise BE
78
	retvalue		rd 1		; 0 (error) or pointer to image
79
endl
80
 
7735 dunkaist 81
	push	ebx esi edi
2388 dunkaist 82
 
83
	mov	esi, [_data]
84
	lodsw
85
	mov	[_endianness], 0
86
	cmp	ax, word 'II'
87
	seta	byte[_endianness]
88
 
89
	lodsw_
90
	lodsd_
91
    @@:
7735 dunkaist 92
;	push	eax
2388 dunkaist 93
	stdcall	tiff._.parse_IFD, [_data], eax, [_endianness]
7735 dunkaist 94
;	pop	esi
95
;	mov	ebx, eax
96
;	mov	[retvalue], eax
97
;	xor	eax, eax
98
;	lodsw_
99
;	shl	eax, 2
100
;	lea	eax, [eax*3]
101
;	add	esi, eax
102
;	lodsd_
103
;	test	eax, eax
2388 dunkaist 104
;	jnz	@b
7735 dunkaist 105
;  .quit:
106
;	mov	eax, [retvalue]
107
	pop	edi esi ebx
2388 dunkaist 108
	ret
109
endp
110
 
111
 
112
;;================================================================================================;;
113
proc img.encode.tiff _img, _p_length, _options ;//////////////////////////////////////////////////;;
114
;;------------------------------------------------------------------------------------------------;;
115
;? Encode image into raw data in tiff format                                                      ;;
116
;;------------------------------------------------------------------------------------------------;;
117
;> _img = pointer to image                                                                        ;;
118
;;------------------------------------------------------------------------------------------------;;
119
;< eax = 0 (error) or pointer to encoded data                                                     ;;
120
;< _p_length = encoded data length                                                                ;;
121
;;================================================================================================;;
122
	xor	eax, eax
123
	ret
124
endp
125
 
126
 
127
;;================================================================================================;;
128
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
129
;;================================================================================================;;
130
;! Below are private procs you should never call directly from your code                          ;;
131
;;================================================================================================;;
132
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
133
;;================================================================================================;;
134
proc tiff._.parse_IFD _data, _IFD, _endianness
135
locals
136
	extended		rd	1
137
	retvalue		rd	1
138
	decompress		rd	1
139
endl
140
	push	ebx edx edi
141
	mov	[retvalue], 0
142
 
143
	invoke	mem.alloc, sizeof.tiff_extra
144
	test	eax, eax
145
	jz	.quit
146
	mov	[extended], eax
147
	mov	ebx, eax
148
	mov	edi, eax
149
	mov	ecx, sizeof.tiff_extra/4
150
	xor	eax, eax
151
	rep	stosd
152
 
153
	mov	esi, [_IFD]
154
	add	esi, [_data]
155
	lodsw_
156
	movzx	ecx, ax
157
    @@:
158
	push	ecx
159
	stdcall	tiff._.parse_IFDE, [_data], [_endianness]
160
	pop	ecx
161
	dec	ecx
162
	jnz	@b
163
 
164
	call	tiff._.define_image_type
165
 
166
	stdcall	img.create, [ebx + tiff_extra.image_width], [ebx + tiff_extra.image_height], eax
167
	test	eax, eax
168
	jz	.quit
169
	mov	[retvalue], eax
170
	mov	edx, eax
171
	mov	[edx + Image.Extended], ebx
172
 
173
	cmp	[ebx+tiff_extra.compression], TIFF.COMPRESSION.UNCOMPRESSED
174
	jne	@f
175
	mov	[decompress], tiff._.decompress.uncompressed
176
	jmp	.decompressor_defined
177
    @@:
178
	cmp	[ebx + tiff_extra.compression], TIFF.COMPRESSION.PACKBITS
179
	jne	@f
180
	mov	[decompress], tiff._.decompress.packbits
181
	jmp	.decompressor_defined
182
    @@:
2992 dunkaist 183
	cmp	[ebx + tiff_extra.compression], TIFF.COMPRESSION.LZW
184
	jne	@f
185
	mov	[decompress], tiff._.decompress.lzw
186
	jmp	.decompressor_defined
187
    @@:
188
	cmp	[ebx + tiff_extra.compression], TIFF.COMPRESSION.CCITT1D
189
	jne	@f
2388 dunkaist 190
	mov	[decompress], tiff._.decompress.ccitt1d
191
	jmp	.decompressor_defined
2992 dunkaist 192
    @@:
193
 
194
	mov	[decompress], 0
2388 dunkaist 195
	jmp	.quit
196
  .decompressor_defined:
197
 
198
	push	esi		; fixme!!
199
 
200
	mov	ecx, [edx + Image.Type]
3499 dunkaist 201
        cmp     ecx, Image.bpp8i
202
        je	.bpp8i
203
        cmp     ecx, Image.bpp24
204
	je	.bpp24
205
        cmp     ecx, Image.bpp32
206
	je	.bpp32
207
        cmp     ecx, Image.bpp16
208
	je	.bpp16
209
        cmp     ecx, Image.bpp1
210
	je	.bpp1
211
        cmp     ecx, Image.bpp8g
212
	je	.bpp8g
213
        cmp     ecx, Image.bpp8a
214
	je	.bpp8a
3503 dunkaist 215
        cmp     ecx, Image.bpp2i
216
	je	.bpp2i
217
        cmp     ecx, Image.bpp4i
218
	je	.bpp4i
3499 dunkaist 219
        jmp     .quit
2388 dunkaist 220
;error report!!
221
 
222
  .bpp1:
223
  .bpp1.palette:
224
	mov	edi, [edx+Image.Palette]
225
	cmp	[ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.BLACK_IS_ZERO
226
	jne	.bpp1.white_is_zero
227
  .bpp1.black_is_zero:
3503 dunkaist 228
	mov	[edi], dword 0xff000000
229
	mov	[edi + 4], dword 0xffffffff
2388 dunkaist 230
	jmp	.common
231
  .bpp1.white_is_zero:
3503 dunkaist 232
	mov	[edi], dword 0xffffffff
233
	mov	[edi + 4], dword 0xff000000
2388 dunkaist 234
	jmp	.common
235
 
3503 dunkaist 236
  .bpp2i:
237
        stdcall tiff._.get_palette, 1 SHL 2, [_endianness]
3499 dunkaist 238
	jmp	.common
239
 
3503 dunkaist 240
  .bpp4i:
241
        stdcall tiff._.get_palette, 1 SHL 4, [_endianness]
2388 dunkaist 242
	jmp	.common
243
 
2733 dunkaist 244
  .bpp8i:
3503 dunkaist 245
        stdcall tiff._.get_palette, 1 SHL 8, [_endianness]
2388 dunkaist 246
	jmp	.common
2733 dunkaist 247
  .bpp8g:
2388 dunkaist 248
	jmp	.common
249
 
2733 dunkaist 250
  .bpp8a:
251
	jmp	.common
252
 
2388 dunkaist 253
  .bpp16:
254
	jmp	.common
255
 
256
  .bpp24:
257
	jmp	.common
258
 
259
  .bpp32:
260
	jmp	.common
261
 
262
 
263
  .common:
264
	mov	edi, [edx+Image.Data]
265
	mov	esi, [ebx+tiff_extra.strip_offsets]
266
	mov	edx, [ebx+tiff_extra.strip_byte_counts]
267
 
268
 
269
	cmp	[ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
270
	jne	.l_x
271
	cmp	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
272
	jne	.s_l
273
	jmp	.s_s
274
  .l_x:	cmp	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
275
	jne	.l_l
276
	jmp	.l_s
277
 
278
  .s_s:
279
	xor	eax, eax
280
	lodsw_
281
	push	esi
282
	mov	esi, eax
283
	add	esi, [_data]
284
	xor	ecx, ecx
285
	mov	cx, word[edx]
286
	test	[_endianness], 1
287
	jz	@f
288
	xchg	cl, ch
289
    @@:
290
	add	edx, 2
291
	stdcall	[decompress], [retvalue]
292
	pop	esi
293
	dec	[ebx + tiff_extra.offsets_number]
294
	jnz	.s_s
295
	jmp	.decoded
296
 
297
  .s_l:
298
	xor	eax, eax
299
	lodsw_
300
	push	esi
301
	mov	esi, eax
302
	add	esi, [_data]
303
	mov	ecx, [edx]
304
	test	[_endianness], 1
305
	jz	@f
306
	bswap	ecx
307
    @@:
308
	add	edx, 4
309
	stdcall	[decompress], [retvalue]
310
	pop	esi
311
	dec	[ebx + tiff_extra.offsets_number]
312
	jnz	.s_l
313
	jmp	.decoded
314
 
315
  .l_s:
316
	lodsd_
317
	push	esi
318
	mov	esi, eax
319
	add	esi, [_data]
320
	xor	ecx, ecx
321
	mov	cx, word[edx]
322
	test	[_endianness], 1
323
	jz	@f
324
	xchg	cl, ch
325
    @@:
326
	add	edx, 2
327
	stdcall	[decompress], [retvalue]
328
	pop	esi
329
	dec	[ebx + tiff_extra.offsets_number]
330
	jnz	.l_s
331
	jmp	.decoded
332
 
333
  .l_l:
334
	lodsd_
335
	push	esi
336
	mov	esi, eax
337
	add	esi, [_data]
338
	mov	ecx, [edx]
339
	test	[_endianness], 1
340
	jz	@f
341
	bswap	ecx
342
    @@:
343
	add	edx, 4
344
	stdcall	[decompress], [retvalue]
345
	pop	esi
346
	dec	[ebx + tiff_extra.offsets_number]
347
	jnz	.l_l
348
	jmp	.decoded
349
 
350
 
351
  .decoded:
3499 dunkaist 352
        cmp     [ebx + tiff_extra.planar_configuration], TIFF.PLANAR.PLANAR
353
        jne     .post.rgb_bgr
354
        stdcall tiff._.planar_to_separate, [retvalue]
2992 dunkaist 355
  .post.rgb_bgr:
2388 dunkaist 356
	cmp	[ebx + tiff_extra.samples_per_pixel], 3
2992 dunkaist 357
	jne	.post.rgba_bgra
2388 dunkaist 358
	mov	eax, [retvalue]
359
	mov	esi, [eax + Image.Data]
360
	mov	edi, [eax + Image.Data]
361
	mov	ecx, [eax + Image.Width]
362
	imul	ecx, [eax + Image.Height]
363
    @@:
364
	lodsw
365
	movsb
366
	mov	byte[esi - 1], al
367
	add	edi, 2
368
	dec	ecx
369
	jnz	@b
7735 dunkaist 370
	jmp	.post.predictor
2992 dunkaist 371
 
372
  .post.rgba_bgra:
373
	cmp	[ebx + tiff_extra.samples_per_pixel], 4
374
	jne	.post.bpp8a_to_bpp8g
375
	mov	eax, [retvalue]
376
	mov	esi, [eax + Image.Data]
377
	mov	edi, [eax + Image.Data]
378
	mov	ecx, [eax + Image.Width]
379
	imul	ecx, [eax + Image.Height]
380
    @@:
381
	lodsw
382
	movsb
383
	mov	byte[esi - 1], al
384
	add	edi, 3
385
	add	esi, 1
386
	dec	ecx
387
	jnz	@b
7735 dunkaist 388
	jmp	.post.predictor
2992 dunkaist 389
 
390
  .post.bpp8a_to_bpp8g:
391
	mov	eax, [retvalue]
392
	cmp	[eax + Image.Type], Image.bpp8a
393
	jne	.post.predictor
2733 dunkaist 394
	mov	ebx, [retvalue]
395
	stdcall	tiff._.pack_8a, ebx
396
	mov	[ebx + Image.Type], Image.bpp8g
2388 dunkaist 397
 
2992 dunkaist 398
  .post.predictor:
399
	cmp	[ebx + tiff_extra.predictor], 2		; Horizontal differencing
400
	jne	.post.end
3053 dunkaist 401
	cmp	[ebx + tiff_extra.image_width], 1
402
	je	.post.end
2992 dunkaist 403
	push	ebx
404
	mov	edi, [ebx + tiff_extra.samples_per_pixel]
405
	mov	edx, edi
406
	mov	ebx, [retvalue]
407
  .post.predictor.plane:
408
	mov	esi, [ebx + Image.Data]
409
	sub	esi, 1
410
	add	esi, edx
411
	mov	ecx, [ebx + Image.Height]
412
  .post.predictor.line:
413
	push	ecx
414
	mov	ecx, [ebx + Image.Width]
415
	sub	ecx, 1
416
	mov	ah, byte[esi]
417
	add	esi, edi
418
    @@:
419
	mov	al, byte[esi]
420
	add	al, ah
421
	mov	byte[esi], al
422
	add	esi, edi
423
	shl	eax, 8
424
	dec	ecx
425
	jnz	@b
426
	pop	ecx
427
	dec	ecx
428
	jnz	.post.predictor.line
429
	dec	edx
430
	jnz	.post.predictor.plane
431
	pop	ebx
432
 
433
  .post.end:
434
 
2388 dunkaist 435
  .pop_quit:
436
	pop	esi
437
  .quit:
438
	pop	edi edx ebx
439
	mov	eax, [retvalue]
440
	ret
441
endp
442
 
443
proc tiff._.parse_IFDE _data, _endianness
444
 
445
	push	ebx edx edi
446
 
447
	lodsw_
448
	mov	edx, tiff.IFDE_tag_table.begin
449
	mov	ecx, (tiff.IFDE_tag_table.end-tiff.IFDE_tag_table.begin)/8
450
  .tag:
451
	cmp	ax, word[edx]
452
	jne	@f
453
	lodsw_
454
	jmp	dword[edx + 4]
455
    @@:
456
	add	edx, 8
457
	dec	ecx
458
	jnz	.tag
2992 dunkaist 459
  .tag_default:						; unknown/unsupported/unimportant
2388 dunkaist 460
	lodsw
461
	lodsd
462
	lodsd
2733 dunkaist 463
	jmp	.quit					; just skip it
2388 dunkaist 464
 
2733 dunkaist 465
  .tag_100:						; ImageWidth
2388 dunkaist 466
	cmp	ax, TIFF.IFDE_TYPE.SHORT
467
	jne	@f
468
	lodsd
469
	xor	eax, eax
470
	lodsw_
471
	mov	[ebx + tiff_extra.image_width], eax
472
	lodsw
473
	jmp	.quit
474
    @@:
475
	cmp	ax, TIFF.IFDE_TYPE.LONG
476
	jne	@f
477
	lodsd
478
	lodsd_
479
	mov	[ebx + tiff_extra.image_width], eax
480
	jmp	.quit
481
    @@:
482
	jmp	.quit
483
 
2733 dunkaist 484
  .tag_101:						; ImageHeight
2388 dunkaist 485
	cmp	ax, TIFF.IFDE_TYPE.SHORT
486
	jne	@f
487
	lodsd
488
	xor	eax, eax
489
	lodsw_
490
	mov	[ebx + tiff_extra.image_height], eax
491
	lodsw
492
	jmp	.quit
493
    @@:
494
	cmp	ax, TIFF.IFDE_TYPE.LONG
495
	jne	@f
496
	lodsd
497
	lodsd_
498
	mov	[ebx + tiff_extra.image_height], eax
499
	jmp	.quit
500
    @@:
501
	jmp	.quit
502
 
2733 dunkaist 503
  .tag_102:						; BitsPerSample
2388 dunkaist 504
	lodsd_
505
	imul	eax, TIFF.IFDE_TYPE_LENGTH.SHORT
506
	cmp	eax, 4
507
	ja	@f
508
	xor	eax, eax
509
	lodsw_
510
	mov	[ebx + tiff_extra.bits_per_sample], eax
511
	lodsw
512
	jmp	.quit
513
    @@:
514
	lodsd_
515
	add	eax, [_data]
516
	push	esi
517
	mov	esi, eax
518
	xor	eax, eax
519
	lodsw_
520
	pop	esi
521
	mov	[ebx + tiff_extra.bits_per_sample], eax
522
	jmp	.quit
523
 
2733 dunkaist 524
  .tag_103:						; Compression
2388 dunkaist 525
	cmp	ax, TIFF.IFDE_TYPE.SHORT
526
	jne	@f
527
	lodsd
528
	xor	eax, eax
529
	lodsw_
530
	mov	[ebx + tiff_extra.compression], eax
531
	lodsw
532
	jmp	.quit
533
    @@:
534
	jmp	.quit
535
 
2733 dunkaist 536
  .tag_106:						; PhotometricInterpretation
2388 dunkaist 537
	cmp	ax, TIFF.IFDE_TYPE.SHORT
538
	jne	@f
539
	lodsd
540
	xor	eax, eax
541
	lodsw_
542
	mov	[ebx + tiff_extra.photometric], eax
543
	lodsw
544
	jmp	.quit
545
    @@:
546
 
547
	jmp	.quit
548
 
2733 dunkaist 549
  .tag_111:						; StripOffsets
2388 dunkaist 550
	cmp	ax, TIFF.IFDE_TYPE.SHORT
551
	jne	@f
552
	mov	[ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
553
	jmp	.tag_111.common
554
    @@:
555
	mov	[ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.LONG
556
  .tag_111.common:
557
	lodsd_
558
	mov	[ebx + tiff_extra.offsets_number], eax
559
	imul	eax, [ebx+tiff_extra.strip_offsets_length]
560
	cmp	eax, 4
561
	ja	@f
562
	mov	[ebx + tiff_extra.strip_offsets], esi
563
	lodsd
564
	jmp	.quit
565
    @@:
566
	lodsd_
567
	add	eax, [_data]
568
	mov	[ebx + tiff_extra.strip_offsets], eax
569
	jmp	.quit
570
 
2733 dunkaist 571
  .tag_115:						; SamplesPerPixel
2388 dunkaist 572
	lodsd_
573
	imul	eax, TIFF.IFDE_TYPE_LENGTH.SHORT
574
	cmp	eax, 4
575
	ja	@f
576
	xor	eax, eax
577
	lodsw_
578
	mov	[ebx + tiff_extra.samples_per_pixel], eax
579
	lodsw
580
	jmp	.quit
581
    @@:
582
	lodsd_
583
	add	eax, [_data]
584
	movzx	eax, word[eax]
585
	jmp	.quit
586
 
2733 dunkaist 587
  .tag_116:						; RowsPerStrip
2388 dunkaist 588
	cmp	ax, TIFF.IFDE_TYPE.SHORT
589
	jne	@f
590
	lodsd
591
	xor	eax, eax
592
	lodsw_
593
	mov	[ebx + tiff_extra.rows_per_strip], eax
594
	lodsw
595
	jmp	.quit
596
    @@:
597
	lodsd
598
	lodsd_
599
	mov	[ebx + tiff_extra.rows_per_strip], eax
600
	jmp	.quit
601
 
2733 dunkaist 602
  .tag_117:						; StripByteCounts
2388 dunkaist 603
	cmp	ax, TIFF.IFDE_TYPE.SHORT
604
	jne	@f
605
	mov	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
606
	jmp	.tag_117.common
607
    @@:
608
	mov	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.LONG
609
  .tag_117.common:
610
	lodsd_
611
	imul	eax, [ebx + tiff_extra.strip_byte_counts_length]
612
	cmp	eax, 4
613
	ja	@f
614
	mov	[ebx + tiff_extra.strip_byte_counts], esi
615
	lodsd
616
	jmp	.quit
617
    @@:
618
	lodsd_
619
	add	eax, [_data]
620
	mov	[ebx + tiff_extra.strip_byte_counts], eax
621
	jmp	.quit
622
 
3499 dunkaist 623
  .tag_11c:						; Planar configuration
624
	cmp	ax, TIFF.IFDE_TYPE.SHORT
625
	jne	@f
626
	lodsd
627
	xor	eax, eax
628
	lodsw_
629
	mov	[ebx + tiff_extra.planar_configuration], eax
630
	lodsw
631
    @@:
632
	jmp	.quit
633
 
634
 
2992 dunkaist 635
  .tag_13d:						; Predictor
636
	cmp	ax, TIFF.IFDE_TYPE.SHORT
637
	jne	@f
638
	lodsd
639
	xor	eax, eax
640
	lodsw_
641
	mov	[ebx + tiff_extra.predictor], eax
642
	lodsw
643
    @@:
644
	jmp	.quit
645
 
2733 dunkaist 646
  .tag_140:						; ColorMap
2388 dunkaist 647
	lodsd
648
	lodsd_
649
	add	eax, [_data]
650
	mov	[ebx + tiff_extra.palette], eax
651
	jmp	.quit
2733 dunkaist 652
  .tag_152:						; ExtraSamples
653
	mov	[ebx + tiff_extra.extra_samples], esi
654
	mov	ecx, [ebx + tiff_extra.extra_samples_number]
655
	rep	lodsw	; ignored
656
	jmp	.quit
2388 dunkaist 657
 
658
  .quit:
659
	pop	edi edx ebx
660
	ret
661
endp
662
 
663
 
664
proc tiff._.define_image_type
665
 
666
	xor	eax, eax
667
 
2733 dunkaist 668
	cmp	[ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.RGB
3503 dunkaist 669
	jne	.palette_bilevel_grayscale
2733 dunkaist 670
	mov	eax, -3
671
	add	eax, [ebx + tiff_extra.samples_per_pixel]
672
	mov	[ebx + tiff_extra.extra_samples_number], eax
673
	dec	eax
674
	jns	@f
675
	mov	eax, Image.bpp24
676
	jmp	.quit
677
    @@:
678
	dec	eax
679
	jns	@f
680
	mov	eax, Image.bpp32
681
;	mov	[ebx + tiff_extra.extra_samples_number], 0
682
	jmp	.quit
683
    @@:
3503 dunkaist 684
  .palette_bilevel_grayscale:
685
	cmp	[ebx + tiff_extra.palette], 0
686
	je	.bilevel_grayscale
687
	cmp	[ebx + tiff_extra.bits_per_sample], 2
688
	jg	@f
689
	mov	eax, Image.bpp2i
2388 dunkaist 690
	jmp	.quit
3503 dunkaist 691
    @@:
2388 dunkaist 692
	cmp	[ebx + tiff_extra.bits_per_sample], 4
3503 dunkaist 693
	jg	@f
694
	mov	eax, Image.bpp4i
2388 dunkaist 695
	jmp	.quit
696
    @@:
697
	cmp	[ebx + tiff_extra.bits_per_sample], 8
698
	jne	@f
2733 dunkaist 699
	mov	eax, Image.bpp8i
2388 dunkaist 700
	jmp	.quit
701
    @@:
702
	jmp	.quit
3503 dunkaist 703
  .bilevel_grayscale:
704
	cmp	[ebx + tiff_extra.bits_per_sample], 1
705
	jg	.grayscale
706
	mov	eax, Image.bpp1
707
	jmp	.quit
708
  .grayscale:
709
	cmp	[ebx + tiff_extra.bits_per_sample], 8
710
        jne     .quit
711
	cmp	[ebx + tiff_extra.samples_per_pixel], 1
712
        jne     @f
2733 dunkaist 713
	mov	eax, Image.bpp8g
2388 dunkaist 714
	jmp	.quit
715
    @@:
2733 dunkaist 716
	mov	eax, Image.bpp8a
2388 dunkaist 717
	jmp	.quit
718
  .quit:
719
	ret
720
endp
721
 
722
 
723
proc tiff._.decompress.uncompressed _image
724
 
725
	rep	movsb
726
	ret
727
endp
728
 
729
 
730
proc tiff._.decompress.packbits _image
731
 
3499 dunkaist 732
	push	edx
2388 dunkaist 733
 
734
	mov	edx, ecx
735
 
736
  .decode:
737
	lodsb
738
	dec	edx
739
	cmp	al, 0x80
3499 dunkaist 740
	jb	.different
741
	jg	.identical
2388 dunkaist 742
	test	edx, edx
743
	jz	.quit
744
	jmp	.decode
745
 
746
  .identical:
747
	neg	al
748
	inc	al
749
	movzx	ecx, al
750
	dec	edx
751
	lodsb
752
	rep	stosb
753
	test	edx, edx
754
	jnz	.decode
755
	jmp	.quit
756
 
757
  .different:
758
	movzx	ecx, al
759
	inc	ecx
760
	sub	edx, ecx
761
	rep	movsb
762
	test	edx, edx
763
	jnz	.decode
764
 
765
  .quit:
3499 dunkaist 766
	pop	edx
2388 dunkaist 767
	ret
768
endp
769
 
770
 
771
proc	tiff._.decompress.ccitt1d _image
772
locals
773
	current_tree		rd	1
774
	old_tree		rd	1
775
	width			rd	1
776
	height			rd	1
777
	width_left		rd	1
778
	is_makeup		rd	1
779
endl
780
	push	ebx ecx edx esi
781
	mov	[is_makeup], 0
782
 
783
	mov	ebx, [_image]
784
	push	[ebx + Image.Height]
785
	pop	[height]
786
	push	[ebx + Image.Width]
787
	pop	[width]
788
 
789
	mov	edx, esi
790
  .next_scanline:
791
	push	[width]
792
	pop	[width_left]
793
	dec	[height]
794
	js	.error
795
	mov	[current_tree], tiff._.huffman_tree_white.begin
796
	mov	[old_tree], tiff._.huffman_tree_black.begin
797
	mov	ebx, 0
798
	mov	ecx, 8
799
  .next_run:
800
	mov	esi, [current_tree]
801
  .branch:
802
	lodsd
803
	btr	eax, 31
804
	jnc	.not_a_leaf
805
	cmp	eax, 63
806
	seta	byte[is_makeup]
807
	ja	@f
808
	push	[current_tree]
809
	push	[old_tree]
810
	pop	[current_tree]
811
	pop	[old_tree]
812
    @@:
813
	stdcall	tiff._.write_run, [width_left], [current_tree]
814
	mov	[width_left], eax
815
	test	byte[is_makeup], 0x01
816
	jnz	.next_run
817
	test	eax, eax
818
	jnz	.next_run
819
	jmp	.next_scanline
820
  .not_a_leaf:
821
	test	bh, bh
822
	jnz	@f
823
	mov	bl, byte[edx]
824
	inc	edx
825
	mov	bh, 8
826
    @@:
827
	test	al, 0x02
828
	jz	.not_a_corner
829
	dec	bh
830
	sal	bl, 1
831
	lahf
832
	and	ah, 0x03
833
	cmp	al, ah
834
	jne	.error
835
	mov	esi, [esi]
836
	jmp	.branch
837
  .not_a_corner:
838
	lodsd
839
	dec	bh
840
	sal	bl, 1
841
	jc	.branch
842
	mov	esi, eax
843
	jmp	.branch
844
  .error:
845
  .quit:
846
	pop	esi edx ecx ebx
847
	ret
848
endp
849
 
7735 dunkaist 850
struct lzw_ctx
851
	bits_left	 dd ?	; in current byte (pointed to by [esi])
852
	cur_shift	 dd ?	; 9 -- 12
853
	shift_counter	 dd ?	; how many shifts of current length remained
854
	table		 dd ?
855
	last_table_entry dd ?	; zero based
856
	next_table_entry dd ?	; where to place new entry
857
	strip_len	 dd ?
858
	old_code	 dd ?
859
ends
2388 dunkaist 860
 
7735 dunkaist 861
proc tiff._.lzw_get_code
862
	mov	edx, [ebx+lzw_ctx.cur_shift]
2992 dunkaist 863
	xor	eax, eax
864
	lodsb
7735 dunkaist 865
	mov	ecx, [ebx+lzw_ctx.bits_left]
2992 dunkaist 866
	mov	ch, cl
867
	neg	cl
868
	add	cl, 8
869
	shl	al, cl
870
	mov	cl, ch
871
	shl	eax, cl
7735 dunkaist 872
	sub	edx, [ebx+lzw_ctx.bits_left]
2992 dunkaist 873
	; second_byte
874
	cmp	edx, 8
875
	je	.enough_zero
876
	jb	.enough_nonzero
877
	sub	edx, 8
878
	lodsb
879
	shl	eax, 8
7735 dunkaist 880
	jmp	.enough_nonzero
2992 dunkaist 881
  .enough_zero:
7735 dunkaist 882
	mov	[ebx+lzw_ctx.bits_left], 8
2992 dunkaist 883
	lodsb
884
	jmp	.code_done
885
  .enough_nonzero:
886
	mov	al, byte[esi]
887
	neg	edx
888
	add	edx, 8
889
	mov	ecx, edx
7735 dunkaist 890
	mov	[ebx+lzw_ctx.bits_left], edx
2992 dunkaist 891
	shr	eax, cl
892
  .code_done:
7735 dunkaist 893
	dec	[ebx+lzw_ctx.shift_counter]
894
	jnz	@f
895
	mov	ecx, [ebx+lzw_ctx.cur_shift]
896
	add	[ebx+lzw_ctx.cur_shift], 1
897
	mov	edx, 1
898
	shl	edx, cl
899
	mov	[ebx+lzw_ctx.shift_counter], edx
900
    @@:
901
	ret
902
endp
2992 dunkaist 903
 
7735 dunkaist 904
proc tiff._.add_string_to_table uses esi
905
	mov	esi, [ebx+lzw_ctx.table]
906
	lea	esi, [esi + eax*8 + 256]
907
	mov	ecx, dword[esi+4]
2992 dunkaist 908
 
7735 dunkaist 909
	mov	edx, [ebx+lzw_ctx.next_table_entry]
910
	mov	[edx], edi
911
	lea	eax, [ecx + 1]
912
	mov	[edx + 4], eax
913
	add	[ebx+lzw_ctx.next_table_entry], 8
914
	add	[ebx+lzw_ctx.last_table_entry], 1
2992 dunkaist 915
 
7735 dunkaist 916
	mov	esi, [esi]
917
	cmp	ecx, [ebx+lzw_ctx.strip_len]
918
	cmovg	ecx, [ebx+lzw_ctx.strip_len]
919
	sub	[ebx+lzw_ctx.strip_len], ecx
920
	rep	movsb
921
	ret
922
endp
923
 
924
proc tiff._.init_code_table
925
	cmp	[ebx+lzw_ctx.table], 0
2992 dunkaist 926
	jne	@f
927
	invoke	mem.alloc, 256 + 63488	; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
928
	test	eax, eax
929
	jz	.quit
7735 dunkaist 930
	mov	[ebx+lzw_ctx.table], eax
2992 dunkaist 931
    @@:
7735 dunkaist 932
	mov	eax, [ebx+lzw_ctx.table]
933
	mov	[ebx+lzw_ctx.next_table_entry], eax
934
	add	[ebx+lzw_ctx.next_table_entry], 256 + (256*8) + 2*8
935
	mov	[ebx+lzw_ctx.cur_shift], 9
936
	mov	[ebx+lzw_ctx.shift_counter], 256-2	; clear code, end of information
937
	mov	[ebx+lzw_ctx.last_table_entry], 257	; 0--255, clear, eoi
2992 dunkaist 938
 
939
	push	edi
940
	mov	ecx, 256
7735 dunkaist 941
	mov	edi, [ebx+lzw_ctx.table]
942
	mov	edx, edi
2992 dunkaist 943
	add	edi, 256
944
	mov	eax, 0
945
    @@:
7735 dunkaist 946
	mov	byte[edx], al
947
	mov	[edi], edx
2992 dunkaist 948
	add	edi, 4
7735 dunkaist 949
	add	edx, 1
2992 dunkaist 950
	add	eax, 1
951
	mov	[edi], dword 1
952
	add	edi, 4
953
	dec	ecx
954
	jnz	@b
955
	pop	edi
7735 dunkaist 956
.quit:
957
	ret
958
endp
2992 dunkaist 959
 
7735 dunkaist 960
proc tiff._.decompress.lzw _image
961
locals
962
	ctx			lzw_ctx
963
endl
964
	push	ebx ecx edx esi
965
	mov	ecx, [ebx+tiff_extra.rows_per_strip]
966
	mov	ebx, [_image]
967
	mov	eax, [ebx+Image.Width]
968
	call	img._.get_scanline_len
969
	imul	eax, ecx
2992 dunkaist 970
 
7735 dunkaist 971
	lea	ebx, [ctx]
972
	mov	[ctx.strip_len], eax
973
	mov	[ctx.table], 0
974
	mov	[ctx.bits_left], 8
975
	mov	[ctx.cur_shift], 9
2992 dunkaist 976
 
7735 dunkaist 977
  .begin:
978
	cmp	[ctx.strip_len], 0
979
	jle	.quit
980
	stdcall	tiff._.lzw_get_code
2992 dunkaist 981
	cmp	eax, 0x101	; end of information
982
	je	.quit
7735 dunkaist 983
	cmp	eax, 0x100	; clear code
984
	jne	.no_clear_code
985
	call	tiff._.init_code_table
2992 dunkaist 986
 
7735 dunkaist 987
	; getnextcode
988
	call	tiff._.lzw_get_code
989
	mov	[ctx.old_code], eax
990
	cmp	eax, 0x101	; end of information
991
	je	.quit
992
	call	tiff._.add_string_to_table
2992 dunkaist 993
	jmp	.begin
994
  .no_clear_code:
7735 dunkaist 995
	cmp	eax, [ctx.last_table_entry]
2992 dunkaist 996
	ja	.not_in_table
7735 dunkaist 997
	mov	[ctx.old_code], eax
998
	call	tiff._.add_string_to_table
2992 dunkaist 999
	jmp	.begin
1000
  .not_in_table:
7735 dunkaist 1001
	xchg	eax, [ctx.old_code]
1002
	call	tiff._.add_string_to_table
1003
	cmp	[ctx.strip_len], 0
1004
	jle	@f
1005
	dec	[ctx.strip_len]
2992 dunkaist 1006
	mov	byte[edi], al
1007
	add	edi, 1
1008
    @@:
1009
	jmp	.begin
1010
  .quit:
7735 dunkaist 1011
	cmp	[ctx.table], 0
2992 dunkaist 1012
	je	@f
7735 dunkaist 1013
	invoke	mem.free, [ctx.table]
2992 dunkaist 1014
    @@:
1015
	pop	esi edx ecx ebx
1016
	ret
1017
endp
1018
 
1019
 
2388 dunkaist 1020
proc	tiff._.write_run _width_left, _current_tree
1021
 
1022
	push	ebx
1023
 
1024
	test	eax, eax
1025
	jz	.done
1026
	sub	[_width_left], eax
1027
	js	.error
1028
	cmp	esi, tiff._.huffman_tree_black.begin
1029
	seta	bh
1030
 
1031
	cmp	ecx, eax
1032
	ja	.one_byte
1033
  .many_bytes:
1034
	mov	bl, [edi]
1035
    @@:
1036
	shl	bl, 1
1037
	or	bl, bh
1038
	dec	eax
1039
	dec	ecx
1040
	jnz	@b
1041
	mov	[edi], bl
1042
	inc	edi
1043
	mov	ecx, eax
1044
	and	eax, 0x07
1045
	shr	ecx, 3
1046
 
1047
	push	eax
1048
	xor	eax, eax
1049
	test	bh, bh
1050
	jz	@f
1051
	dec	al
1052
    @@:
1053
	rep	stosb
1054
	pop	eax
1055
 
1056
	mov	ecx, 8
1057
	test	eax, eax
1058
	jz	.done
1059
 
1060
  .one_byte:
1061
	mov	bl, [edi]
1062
    @@:
1063
	shl	bl, 1
1064
	or	bl, bh
1065
	dec	ecx
1066
	dec	eax
1067
	jnz	@b
1068
	mov	byte[edi], bl
1069
 
1070
	cmp	[_width_left], 0
1071
	jne	.done
1072
	mov	bl, [edi]
1073
	shl	bl, cl
1074
	mov	byte[edi], bl
1075
	inc	edi
1076
  .done:
1077
	mov	eax, [_width_left]
1078
	jmp	.quit
1079
  .error:
1080
  .quit:
1081
	pop	ebx
1082
	ret
1083
endp
1084
 
1085
 
1086
proc	tiff._.get_word _endianness
1087
 
1088
	lodsw
1089
	test	[_endianness], 1
1090
	jnz	@f
1091
	ret
1092
    @@:
1093
	xchg	al, ah
1094
	ret
1095
endp
1096
 
1097
 
1098
proc	tiff._.get_dword _endianness
1099
 
1100
	lodsd
1101
	test	[_endianness], 1
1102
	jnz	@f
1103
	ret
1104
    @@:
1105
	bswap	eax
1106
	ret
1107
 
1108
	ret
1109
endp
1110
 
1111
 
2733 dunkaist 1112
proc	tiff._.pack_8a _img
1113
	mov	ebx, [_img]
1114
	mov	esi, [ebx + Image.Data]
1115
	mov	edi, esi
1116
	mov	ecx, [ebx + Image.Width]
1117
	imul	ecx, [ebx + Image.Height]
1118
    @@:
1119
	lodsw
1120
	stosb
1121
	dec	ecx
1122
	jnz	@b
1123
	ret
1124
endp
1125
 
3499 dunkaist 1126
 
1127
proc tiff._.planar_to_separate _img
1128
locals
1129
        pixels          rd 1
1130
        tmp_image       rd 1
1131
        channels        rd 1
1132
        channel_padding rd 1
1133
endl
1134
        pushad
1135
        mov     ebx, [_img]
1136
        mov     ecx, [ebx + Image.Width]
1137
        imul    ecx, [ebx + Image.Height]
1138
        mov     [pixels], ecx
1139
        cmp     [ebx + Image.Type], Image.bpp24
1140
        je      .bpp24
1141
        cmp     [ebx + Image.Type], Image.bpp32
1142
        je      .bpp32
1143
;        cmp     [ebx + Image.Type], Image.bpp4
1144
;        je      .bpp4
1145
        jmp     .quit
1146
  .bpp24:
1147
        mov     [channels], 3
1148
        mov     [channel_padding], 2
1149
        lea     eax, [ecx*3]
1150
        jmp     .proceed
1151
  .bpp32:
1152
        mov     [channels], 4
1153
        mov     [channel_padding], 3
1154
        shl     eax, 2
1155
        jmp     .proceed
1156
  .bpp4:
1157
        mov     [channels], 3
1158
        mov     [channel_padding], 2
1159
        shr     eax, 1
1160
        jmp     .proceed
1161
  .proceed:
1162
        invoke  mem.alloc, eax
1163
        test    eax, eax
1164
        jz      .quit
1165
        mov     [tmp_image], eax
1166
  .channel:
1167
        mov     esi, [ebx + Image.Data]
1168
        mov     edi, [tmp_image]
1169
        mov     ecx, [pixels]
1170
        mov     eax, [channel_padding]
1171
        inc     eax
1172
        sub     eax, [channels]
1173
        add     edi, eax
1174
        mov     eax, [channels]
1175
        dec     eax
1176
        imul    eax, [pixels]
1177
        add     esi, eax
1178
    @@:
1179
        lodsb
1180
        stosb
1181
        add     edi, [channel_padding]
1182
        dec     ecx
1183
        jnz     @b
1184
        dec     [channels]
1185
        jnz     .channel
1186
 
1187
  .quit:
1188
        mov     eax, [tmp_image]
1189
        xchg    [ebx + Image.Data], eax
1190
        invoke  mem.free, eax
1191
        popad
1192
        ret
1193
endp
1194
 
3503 dunkaist 1195
 
1196
proc tiff._.get_palette _num_colors, _endianness
1197
	mov	esi, [ebx + tiff_extra.palette]
1198
        push    ebx
1199
	mov	ebx, 2
1200
  .bpp2.channel:
1201
	mov	edi, ebx
1202
	add	edi, [edx + Image.Palette]
1203
	mov	ecx, [_num_colors]
1204
    @@:
1205
        lodsw_
1206
        shr     eax, 8
1207
        stosb
1208
	add	edi, 3
1209
	dec	ecx
1210
	jnz	@b
1211
	dec	ebx
1212
	jns	.bpp2.channel
1213
        pop     ebx
1214
        ret
1215
endp
1216
 
2388 dunkaist 1217
;;================================================================================================;;
1218
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1219
;;================================================================================================;;
1220
;! Below is private data you should never use directly from your code                             ;;
1221
;;================================================================================================;;
1222
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1223
;;================================================================================================;;
1224
tiff.IFDE_tag_table.begin:
1225
  .tag_100:		dd	0x0100,	tiff._.parse_IFDE.tag_100		; image width
1226
  .tag_101:		dd	0x0101,	tiff._.parse_IFDE.tag_101		; image height (this is called 'length' in spec)
1227
  .tag_102:		dd	0x0102,	tiff._.parse_IFDE.tag_102		; bits per sample
1228
  .tag_103:		dd	0x0103,	tiff._.parse_IFDE.tag_103		; compression
1229
  .tag_106:		dd	0x0106,	tiff._.parse_IFDE.tag_106		; photometric interpretation
1230
  .tag_111:		dd	0x0111,	tiff._.parse_IFDE.tag_111		; strip offsets
1231
  .tag_115:		dd	0x0115,	tiff._.parse_IFDE.tag_115		; samples per pixel
1232
  .tag_116:		dd	0x0116,	tiff._.parse_IFDE.tag_116		; rows per strip
1233
  .tag_117:		dd	0x0117,	tiff._.parse_IFDE.tag_117		; strip byte counts
3499 dunkaist 1234
  .tag_11c:		dd	0x011c,	tiff._.parse_IFDE.tag_11c		; planar configuration
2992 dunkaist 1235
  .tag_13d:		dd	0x013d,	tiff._.parse_IFDE.tag_13d		; predictor
2388 dunkaist 1236
  .tag_140:		dd	0x0140,	tiff._.parse_IFDE.tag_140		; color map
2733 dunkaist 1237
  .tag_152:		dd	0x0152,	tiff._.parse_IFDE.tag_152		; extra samples
2388 dunkaist 1238
tiff.IFDE_tag_table.end:
1239
 
1240
include 'huffman.asm'		; huffman trees for ccitt1d compression method