Subversion Repositories Kolibri OS

Rev

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