Subversion Repositories Kolibri OS

Rev

Rev 2992 | Rev 3499 | 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
3053 dunkaist 398
	cmp	[ebx + tiff_extra.image_width], 1
399
	je	.post.end
2992 dunkaist 400
	push	ebx
401
	mov	edi, [ebx + tiff_extra.samples_per_pixel]
402
	mov	edx, edi
403
	mov	ebx, [retvalue]
404
  .post.predictor.plane:
405
	mov	esi, [ebx + Image.Data]
406
	sub	esi, 1
407
	add	esi, edx
408
	mov	ecx, [ebx + Image.Height]
409
  .post.predictor.line:
410
	push	ecx
411
	mov	ecx, [ebx + Image.Width]
412
	sub	ecx, 1
413
	mov	ah, byte[esi]
414
	add	esi, edi
415
    @@:
416
	mov	al, byte[esi]
417
	add	al, ah
418
	mov	byte[esi], al
419
	add	esi, edi
420
	shl	eax, 8
421
	dec	ecx
422
	jnz	@b
423
	pop	ecx
424
	dec	ecx
425
	jnz	.post.predictor.line
426
	dec	edx
427
	jnz	.post.predictor.plane
428
	pop	ebx
429
 
430
  .post.end:
431
 
2388 dunkaist 432
  .pop_quit:
433
	pop	esi
434
  .quit:
435
	pop	edi edx ebx
436
	mov	eax, [retvalue]
437
	ret
438
endp
439
 
440
proc tiff._.parse_IFDE _data, _endianness
441
 
442
	push	ebx edx edi
443
 
444
	lodsw_
445
	mov	edx, tiff.IFDE_tag_table.begin
446
	mov	ecx, (tiff.IFDE_tag_table.end-tiff.IFDE_tag_table.begin)/8
447
  .tag:
448
	cmp	ax, word[edx]
449
	jne	@f
450
	lodsw_
451
	jmp	dword[edx + 4]
452
    @@:
453
	add	edx, 8
454
	dec	ecx
455
	jnz	.tag
2992 dunkaist 456
  .tag_default:						; unknown/unsupported/unimportant
2388 dunkaist 457
	lodsw
458
	lodsd
459
	lodsd
2733 dunkaist 460
	jmp	.quit					; just skip it
2388 dunkaist 461
 
2733 dunkaist 462
  .tag_100:						; ImageWidth
2388 dunkaist 463
	cmp	ax, TIFF.IFDE_TYPE.SHORT
464
	jne	@f
465
	lodsd
466
	xor	eax, eax
467
	lodsw_
468
	mov	[ebx + tiff_extra.image_width], eax
469
	lodsw
470
	jmp	.quit
471
    @@:
472
	cmp	ax, TIFF.IFDE_TYPE.LONG
473
	jne	@f
474
	lodsd
475
	lodsd_
476
	mov	[ebx + tiff_extra.image_width], eax
477
	jmp	.quit
478
    @@:
479
	jmp	.quit
480
 
2733 dunkaist 481
  .tag_101:						; ImageHeight
2388 dunkaist 482
	cmp	ax, TIFF.IFDE_TYPE.SHORT
483
	jne	@f
484
	lodsd
485
	xor	eax, eax
486
	lodsw_
487
	mov	[ebx + tiff_extra.image_height], eax
488
	lodsw
489
	jmp	.quit
490
    @@:
491
	cmp	ax, TIFF.IFDE_TYPE.LONG
492
	jne	@f
493
	lodsd
494
	lodsd_
495
	mov	[ebx + tiff_extra.image_height], eax
496
	jmp	.quit
497
    @@:
498
	jmp	.quit
499
 
2733 dunkaist 500
  .tag_102:						; BitsPerSample
2388 dunkaist 501
	lodsd_
502
	imul	eax, TIFF.IFDE_TYPE_LENGTH.SHORT
503
	cmp	eax, 4
504
	ja	@f
505
	xor	eax, eax
506
	lodsw_
507
	mov	[ebx + tiff_extra.bits_per_sample], eax
508
	lodsw
509
	jmp	.quit
510
    @@:
511
	lodsd_
512
	add	eax, [_data]
513
	push	esi
514
	mov	esi, eax
515
	xor	eax, eax
516
	lodsw_
517
	pop	esi
518
	mov	[ebx + tiff_extra.bits_per_sample], eax
519
	jmp	.quit
520
 
2733 dunkaist 521
  .tag_103:						; Compression
2388 dunkaist 522
	cmp	ax, TIFF.IFDE_TYPE.SHORT
523
	jne	@f
524
	lodsd
525
	xor	eax, eax
526
	lodsw_
527
	mov	[ebx + tiff_extra.compression], eax
528
	lodsw
529
	jmp	.quit
530
    @@:
531
	jmp	.quit
532
 
2733 dunkaist 533
  .tag_106:						; PhotometricInterpretation
2388 dunkaist 534
	cmp	ax, TIFF.IFDE_TYPE.SHORT
535
	jne	@f
536
	lodsd
537
	xor	eax, eax
538
	lodsw_
539
	mov	[ebx + tiff_extra.photometric], eax
540
	lodsw
541
	jmp	.quit
542
    @@:
543
 
544
	jmp	.quit
545
 
2733 dunkaist 546
  .tag_111:						; StripOffsets
2388 dunkaist 547
	cmp	ax, TIFF.IFDE_TYPE.SHORT
548
	jne	@f
549
	mov	[ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.SHORT
550
	jmp	.tag_111.common
551
    @@:
552
	mov	[ebx + tiff_extra.strip_offsets_length], TIFF.IFDE_TYPE_LENGTH.LONG
553
  .tag_111.common:
554
	lodsd_
555
	mov	[ebx + tiff_extra.offsets_number], eax
556
	imul	eax, [ebx+tiff_extra.strip_offsets_length]
557
	cmp	eax, 4
558
	ja	@f
559
	mov	[ebx + tiff_extra.strip_offsets], esi
560
	lodsd
561
	jmp	.quit
562
    @@:
563
	lodsd_
564
	add	eax, [_data]
565
	mov	[ebx + tiff_extra.strip_offsets], eax
566
	jmp	.quit
567
 
2733 dunkaist 568
  .tag_115:						; SamplesPerPixel
2388 dunkaist 569
	lodsd_
570
	imul	eax, TIFF.IFDE_TYPE_LENGTH.SHORT
571
	cmp	eax, 4
572
	ja	@f
573
	xor	eax, eax
574
	lodsw_
575
	mov	[ebx + tiff_extra.samples_per_pixel], eax
576
	lodsw
577
	jmp	.quit
578
    @@:
579
	lodsd_
580
	add	eax, [_data]
581
	movzx	eax, word[eax]
582
	jmp	.quit
583
 
2733 dunkaist 584
  .tag_116:						; RowsPerStrip
2388 dunkaist 585
	cmp	ax, TIFF.IFDE_TYPE.SHORT
586
	jne	@f
587
	lodsd
588
	xor	eax, eax
589
	lodsw_
590
	mov	[ebx + tiff_extra.rows_per_strip], eax
591
	lodsw
592
	jmp	.quit
593
    @@:
594
	lodsd
595
	lodsd_
596
	mov	[ebx + tiff_extra.rows_per_strip], eax
597
	jmp	.quit
598
 
2733 dunkaist 599
  .tag_117:						; StripByteCounts
2388 dunkaist 600
	cmp	ax, TIFF.IFDE_TYPE.SHORT
601
	jne	@f
602
	mov	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.SHORT
603
	jmp	.tag_117.common
604
    @@:
605
	mov	[ebx + tiff_extra.strip_byte_counts_length], TIFF.IFDE_TYPE_LENGTH.LONG
606
  .tag_117.common:
607
	lodsd_
608
	imul	eax, [ebx + tiff_extra.strip_byte_counts_length]
609
	cmp	eax, 4
610
	ja	@f
611
	mov	[ebx + tiff_extra.strip_byte_counts], esi
612
	lodsd
613
	jmp	.quit
614
    @@:
615
	lodsd_
616
	add	eax, [_data]
617
	mov	[ebx + tiff_extra.strip_byte_counts], eax
618
	jmp	.quit
619
 
2992 dunkaist 620
  .tag_13d:						; Predictor
621
	cmp	ax, TIFF.IFDE_TYPE.SHORT
622
	jne	@f
623
	lodsd
624
	xor	eax, eax
625
	lodsw_
626
	mov	[ebx + tiff_extra.predictor], eax
627
	lodsw
628
    @@:
629
	jmp	.quit
630
 
2733 dunkaist 631
  .tag_140:						; ColorMap
2388 dunkaist 632
	lodsd
633
	lodsd_
634
	add	eax, [_data]
635
	mov	[ebx + tiff_extra.palette], eax
636
	jmp	.quit
2733 dunkaist 637
  .tag_152:						; ExtraSamples
638
	mov	[ebx + tiff_extra.extra_samples], esi
639
	mov	ecx, [ebx + tiff_extra.extra_samples_number]
640
	rep	lodsw	; ignored
641
	jmp	.quit
2388 dunkaist 642
 
643
  .quit:
644
	pop	edi edx ebx
645
	ret
646
endp
647
 
648
 
649
proc tiff._.define_image_type
650
 
651
	xor	eax, eax
652
 
2733 dunkaist 653
	cmp	[ebx + tiff_extra.photometric], TIFF.PHOTOMETRIC.RGB
654
	jne	.not_full_color
655
	mov	eax, -3
656
	add	eax, [ebx + tiff_extra.samples_per_pixel]
657
	mov	[ebx + tiff_extra.extra_samples_number], eax
658
	dec	eax
659
	jns	@f
660
	mov	eax, Image.bpp24
661
	jmp	.quit
662
    @@:
663
	dec	eax
664
	jns	@f
665
	mov	eax, Image.bpp32
666
;	mov	[ebx + tiff_extra.extra_samples_number], 0
667
	jmp	.quit
668
    @@:
669
  .not_full_color:	; grayscale, indexed, bilevel
2388 dunkaist 670
	cmp	[ebx + tiff_extra.bits_per_sample], 1
671
	jg	.not_bilevel
672
	mov	eax, Image.bpp1
673
	jmp	.quit
2733 dunkaist 674
  .not_bilevel:		; grayscale, indexed
2388 dunkaist 675
	cmp	[ebx + tiff_extra.palette], 0
676
	je	.without_palette
677
	cmp	[ebx + tiff_extra.bits_per_sample], 4
678
	jne	@f
2733 dunkaist 679
;	mov	eax, Image.bpp4
2388 dunkaist 680
	jmp	.quit
681
    @@:
682
	cmp	[ebx + tiff_extra.bits_per_sample], 8
683
	jne	@f
2733 dunkaist 684
	mov	eax, Image.bpp8i
2388 dunkaist 685
	jmp	.quit
686
    @@:
687
	jmp	.quit
2733 dunkaist 688
  .without_palette:	; grayscale
689
	mov	eax, -1
690
	add	eax, [ebx + tiff_extra.samples_per_pixel]
691
	mov	[ebx + tiff_extra.extra_samples_number], eax
692
	dec	eax
693
	jns	@f
694
	mov	eax, Image.bpp8g
2388 dunkaist 695
	jmp	.quit
696
    @@:
2733 dunkaist 697
	mov	eax, Image.bpp8a
2388 dunkaist 698
	jmp	.quit
699
  .quit:
700
	ret
701
endp
702
 
703
 
704
proc tiff._.decompress.uncompressed _image
705
 
706
	rep	movsb
707
	ret
708
endp
709
 
710
 
711
proc tiff._.decompress.packbits _image
712
 
713
	push	ebx ecx edx esi
714
 
715
	mov	edx, ecx
716
 
717
  .decode:
718
	lodsb
719
	dec	edx
2397 dunkaist 720
	cmp	al, 0x7f
2388 dunkaist 721
	jbe	.different
722
	cmp	al, 0x80
723
	jne	.identical
724
	test	edx, edx
725
	jz	.quit
726
	jmp	.decode
727
 
728
  .identical:
729
	neg	al
730
	inc	al
731
	movzx	ecx, al
732
	dec	edx
733
	lodsb
734
	rep	stosb
735
	test	edx, edx
736
	jnz	.decode
737
	jmp	.quit
738
 
739
  .different:
740
	movzx	ecx, al
741
	inc	ecx
742
	sub	edx, ecx
743
	rep	movsb
744
	test	edx, edx
745
	jnz	.decode
746
 
747
  .quit:
748
	pop	esi edx ecx ebx
749
	ret
750
endp
751
 
752
 
753
proc	tiff._.decompress.ccitt1d _image
754
locals
755
	current_tree		rd	1
756
	old_tree		rd	1
757
	width			rd	1
758
	height			rd	1
759
	width_left		rd	1
760
	is_makeup		rd	1
761
endl
762
	push	ebx ecx edx esi
763
	mov	[is_makeup], 0
764
 
765
	mov	ebx, [_image]
766
	push	[ebx + Image.Height]
767
	pop	[height]
768
	push	[ebx + Image.Width]
769
	pop	[width]
770
 
771
	mov	edx, esi
772
  .next_scanline:
773
	push	[width]
774
	pop	[width_left]
775
	dec	[height]
776
	js	.error
777
	mov	[current_tree], tiff._.huffman_tree_white.begin
778
	mov	[old_tree], tiff._.huffman_tree_black.begin
779
	mov	ebx, 0
780
	mov	ecx, 8
781
  .next_run:
782
	mov	esi, [current_tree]
783
  .branch:
784
	lodsd
785
	btr	eax, 31
786
	jnc	.not_a_leaf
787
	cmp	eax, 63
788
	seta	byte[is_makeup]
789
	ja	@f
790
	push	[current_tree]
791
	push	[old_tree]
792
	pop	[current_tree]
793
	pop	[old_tree]
794
    @@:
795
	stdcall	tiff._.write_run, [width_left], [current_tree]
796
	mov	[width_left], eax
797
	test	byte[is_makeup], 0x01
798
	jnz	.next_run
799
	test	eax, eax
800
	jnz	.next_run
801
	jmp	.next_scanline
802
  .not_a_leaf:
803
	test	bh, bh
804
	jnz	@f
805
	mov	bl, byte[edx]
806
	inc	edx
807
	mov	bh, 8
808
    @@:
809
	test	al, 0x02
810
	jz	.not_a_corner
811
	dec	bh
812
	sal	bl, 1
813
	lahf
814
	and	ah, 0x03
815
	cmp	al, ah
816
	jne	.error
817
	mov	esi, [esi]
818
	jmp	.branch
819
  .not_a_corner:
820
	lodsd
821
	dec	bh
822
	sal	bl, 1
823
	jc	.branch
824
	mov	esi, eax
825
	jmp	.branch
826
  .error:
827
  .quit:
828
	pop	esi edx ecx ebx
829
	ret
830
endp
831
 
832
 
2992 dunkaist 833
proc tiff._.decompress.lzw _image
834
locals
835
	cur_shift		rd 1	; 9 -- 12
836
	shift_counter		rd 1	; how many shifts of current length remained
837
	bits_left		rd 1	; in current byte ( pointed to by [esi] )
838
	table			rd 1
839
	table_size		rd 1	; the number of entries
840
	old_code		rd 1
841
	next_table_entry	rd 1	; where to place new entry
842
endl
843
	push	ebx ecx edx esi
844
 
845
	mov	[table], 0
846
	mov	[bits_left], 8
847
	mov	[cur_shift], 9
848
 
849
  .begin:
850
 
851
 ; .getnextcode:
852
	xor	eax, eax
853
	mov	edx, [cur_shift]
854
 
855
	lodsb
856
	mov	ecx, [bits_left]
857
	mov	ch, cl
858
	neg	cl
859
	add	cl, 8
860
	shl	al, cl
861
	mov	cl, ch
862
	shl	eax, cl
863
	sub	edx, [bits_left]
864
	; second_byte
865
	cmp	edx, 8
866
	je	.enough_zero
867
	jb	.enough_nonzero
868
	sub	edx, 8
869
	lodsb
870
	shl	eax, 8
871
	jmp	.third_byte
872
  .enough_zero:
873
	mov	[bits_left], 8
874
	lodsb
875
	jmp	.code_done
876
  .enough_nonzero:
877
	mov	al, byte[esi]
878
	neg	edx
879
	add	edx, 8
880
	mov	ecx, edx
881
	mov	[bits_left], edx
882
	shr	eax, cl
883
	jmp	.code_done
884
  .third_byte:
885
	mov	al, byte[esi]
886
	neg	edx
887
	add	edx, 8
888
	mov	ecx, edx
889
	mov	[bits_left], edx
890
	shr	eax, cl
891
  .code_done:
892
 
893
 
894
	mov	ebx, eax
895
	cmp	ebx, 0x101	; end of information
896
	je	.quit
897
	cmp	ebx, 0x100	; clear code
898
	jne	.no_clear_code
899
 
900
	cmp	[table], 0
901
	jne	@f
902
	invoke	mem.alloc, 256 + 63488	; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
903
	test	eax, eax
904
	jz	.quit
905
	mov	[table], eax
906
    @@:
907
	mov	eax, [table]
908
	mov	[next_table_entry], eax
909
	add	[next_table_entry], 256 + (256*8) + 2*8
910
	mov	[cur_shift], 9
911
	mov	[shift_counter], 256-3	; clear code, end of information, why -3?
912
	mov	[table_size], 257
913
 
914
	push	edi
915
	mov	ecx, 256
916
	mov	edi, [table]
917
	mov	ebx, edi
918
	add	edi, 256
919
	mov	eax, 0
920
    @@:
921
	mov	byte[ebx], al
922
	mov	[edi], ebx
923
	add	edi, 4
924
	add	ebx, 1
925
	add	eax, 1
926
	mov	[edi], dword 1
927
	add	edi, 4
928
	dec	ecx
929
	jnz	@b
930
	pop	edi
931
;  .getnextcode:
932
	xor	eax, eax
933
	mov	edx, [cur_shift]
934
 
935
	lodsb
936
	mov	ecx, [bits_left]
937
	mov	ch, cl
938
	neg	cl
939
	add	cl, 8
940
	shl	al, cl
941
	mov	cl, ch
942
	shl	eax, cl
943
	sub	edx, [bits_left]
944
	; second_byte
945
	cmp	edx, 8
946
	je	.enough_zero2
947
	jb	.enough_nonzero2
948
	sub	edx, 8
949
	lodsb
950
	shl	eax, 8
951
	jmp	.third_byte2
952
  .enough_zero2:
953
	mov	[bits_left], 8
954
	lodsb
955
	jmp	.code_done2
956
  .enough_nonzero2:
957
	mov	al, byte[esi]
958
	neg	edx
959
	add	edx, 8
960
	mov	ecx, edx
961
	mov	[bits_left], edx
962
	shr	eax, cl
963
	jmp	.code_done2
964
  .third_byte2:
965
	mov	al, byte[esi]
966
	neg	edx
967
	add	edx, 8
968
	mov	ecx, edx
969
	mov	[bits_left], edx
970
	shr	eax, cl
971
  .code_done2:
972
 
973
 
974
	mov	[old_code], eax
975
	cmp	eax, 0x101	; end of information
976
	je	.quit
977
 
978
	push	esi
979
	mov	esi, [table]
980
	lea	esi, [esi + eax*8 + 256]
981
	mov	ecx, dword[esi+4]
982
 
983
	mov	edx, [next_table_entry]
984
	mov	[edx], edi
985
	lea	eax, [ecx + 1]
986
	mov	[edx + 4], eax
987
	add	[next_table_entry], 8
988
 
989
	mov	esi, [esi]
990
	rep	movsb
991
	pop	esi
992
	jmp	.begin
993
  .no_clear_code:
994
	cmp	eax, [table_size]
995
	ja	.not_in_table
996
	mov	[old_code], eax
997
	push	esi
998
	mov	esi, [table]
999
	lea	esi, [esi + eax*8 + 256]
1000
	mov	ecx, dword[esi + 4]
1001
 
1002
	mov	edx, [next_table_entry]
1003
	mov	[edx], edi
1004
	lea	eax, [ecx + 1]
1005
	mov	[edx + 4], eax
1006
	add	[next_table_entry], 8
1007
	add	[table_size], 1
1008
 
1009
	mov	esi, [esi]
1010
	rep	movsb
1011
	pop	esi
1012
 
1013
	dec	[shift_counter]
1014
	jnz	@f
1015
	mov	ecx, [cur_shift]
1016
	add	[cur_shift], 1
1017
	mov	edx, 1
1018
	shl	edx, cl
1019
	mov	[shift_counter], edx
1020
    @@:
1021
	jmp	.begin
1022
 
1023
  .not_in_table:
1024
	xchg	eax, [old_code]
1025
	push	esi
1026
	mov	esi, [table]
1027
	lea	esi, [esi + eax*8 + 256]
1028
	mov	ecx, dword[esi+4]
1029
 
1030
	mov	edx, [next_table_entry]
1031
	mov	[edx], edi
1032
	lea	eax, [ecx + 2]
1033
	mov	[edx + 4], eax
1034
	add	[next_table_entry], 8
1035
	add	[table_size], 1
1036
 
1037
	mov	esi, [esi]
1038
	mov	al, [esi]
1039
	rep	movsb
1040
	mov	byte[edi], al
1041
	add	edi, 1
1042
	pop	esi
1043
 
1044
	dec	[shift_counter]
1045
	jnz	@f
1046
	mov	ecx, [cur_shift]
1047
	add	[cur_shift], 1
1048
	mov	edx, 1
1049
	shl	edx, cl
1050
	mov	[shift_counter], edx
1051
    @@:
1052
	jmp	.begin
1053
 
1054
  .quit:
1055
	cmp	[table], 0
1056
	je	@f
1057
	invoke	mem.free, [table]
1058
    @@:
1059
	pop	esi edx ecx ebx
1060
	ret
1061
endp
1062
 
1063
 
2388 dunkaist 1064
proc	tiff._.write_run _width_left, _current_tree
1065
 
1066
	push	ebx
1067
 
1068
	test	eax, eax
1069
	jz	.done
1070
	sub	[_width_left], eax
1071
	js	.error
1072
	cmp	esi, tiff._.huffman_tree_black.begin
1073
	seta	bh
1074
 
1075
	cmp	ecx, eax
1076
	ja	.one_byte
1077
  .many_bytes:
1078
	mov	bl, [edi]
1079
    @@:
1080
	shl	bl, 1
1081
	or	bl, bh
1082
	dec	eax
1083
	dec	ecx
1084
	jnz	@b
1085
	mov	[edi], bl
1086
	inc	edi
1087
	mov	ecx, eax
1088
	and	eax, 0x07
1089
	shr	ecx, 3
1090
 
1091
	push	eax
1092
	xor	eax, eax
1093
	test	bh, bh
1094
	jz	@f
1095
	dec	al
1096
    @@:
1097
	rep	stosb
1098
	pop	eax
1099
 
1100
	mov	ecx, 8
1101
	test	eax, eax
1102
	jz	.done
1103
 
1104
  .one_byte:
1105
	mov	bl, [edi]
1106
    @@:
1107
	shl	bl, 1
1108
	or	bl, bh
1109
	dec	ecx
1110
	dec	eax
1111
	jnz	@b
1112
	mov	byte[edi], bl
1113
 
1114
	cmp	[_width_left], 0
1115
	jne	.done
1116
	mov	bl, [edi]
1117
	shl	bl, cl
1118
	mov	byte[edi], bl
1119
	inc	edi
1120
  .done:
1121
	mov	eax, [_width_left]
1122
	jmp	.quit
1123
  .error:
1124
  .quit:
1125
	pop	ebx
1126
	ret
1127
endp
1128
 
1129
 
1130
proc	tiff._.get_word _endianness
1131
 
1132
	lodsw
1133
	test	[_endianness], 1
1134
	jnz	@f
1135
	ret
1136
    @@:
1137
	xchg	al, ah
1138
	ret
1139
endp
1140
 
1141
 
1142
proc	tiff._.get_dword _endianness
1143
 
1144
	lodsd
1145
	test	[_endianness], 1
1146
	jnz	@f
1147
	ret
1148
    @@:
1149
	bswap	eax
1150
	ret
1151
 
1152
	ret
1153
endp
1154
 
1155
 
2733 dunkaist 1156
proc	tiff._.pack_8a _img
1157
	mov	ebx, [_img]
1158
	mov	esi, [ebx + Image.Data]
1159
	mov	edi, esi
1160
	mov	ecx, [ebx + Image.Width]
1161
	imul	ecx, [ebx + Image.Height]
1162
    @@:
1163
	lodsw
1164
	stosb
1165
	dec	ecx
1166
	jnz	@b
1167
	ret
1168
endp
1169
 
2388 dunkaist 1170
;;================================================================================================;;
1171
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1172
;;================================================================================================;;
1173
;! Below is private data you should never use directly from your code                             ;;
1174
;;================================================================================================;;
1175
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1176
;;================================================================================================;;
1177
tiff.IFDE_tag_table.begin:
1178
  .tag_100:		dd	0x0100,	tiff._.parse_IFDE.tag_100		; image width
1179
  .tag_101:		dd	0x0101,	tiff._.parse_IFDE.tag_101		; image height (this is called 'length' in spec)
1180
  .tag_102:		dd	0x0102,	tiff._.parse_IFDE.tag_102		; bits per sample
1181
  .tag_103:		dd	0x0103,	tiff._.parse_IFDE.tag_103		; compression
1182
  .tag_106:		dd	0x0106,	tiff._.parse_IFDE.tag_106		; photometric interpretation
1183
  .tag_111:		dd	0x0111,	tiff._.parse_IFDE.tag_111		; strip offsets
1184
  .tag_115:		dd	0x0115,	tiff._.parse_IFDE.tag_115		; samples per pixel
1185
  .tag_116:		dd	0x0116,	tiff._.parse_IFDE.tag_116		; rows per strip
1186
  .tag_117:		dd	0x0117,	tiff._.parse_IFDE.tag_117		; strip byte counts
2992 dunkaist 1187
  .tag_13d:		dd	0x013d,	tiff._.parse_IFDE.tag_13d		; predictor
2388 dunkaist 1188
  .tag_140:		dd	0x0140,	tiff._.parse_IFDE.tag_140		; color map
2733 dunkaist 1189
  .tag_152:		dd	0x0152,	tiff._.parse_IFDE.tag_152		; extra samples
2388 dunkaist 1190
tiff.IFDE_tag_table.end:
1191
 
1192
include 'huffman.asm'		; huffman trees for ccitt1d compression method