Subversion Repositories Kolibri OS

Rev

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

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