Subversion Repositories Kolibri OS

Rev

Rev 7523 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8341 dunkaist 1
;;================================================================================================;;
2
;;//// bmp.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ///////////////////////////////////;;
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
;; References:                                                                                    ;;
21
;;   1. "Microsoft Windows Bitmap File Format Summary"                                            ;;
22
;;      from "Encyclopedia of Graphics File Formats" by O'Reilly                                  ;;
23
;;      http://www.fileformat.info/format/bmp/                                                    ;;
24
;;                                                                                                ;;
25
;;================================================================================================;;
26
 
27
 
28
include 'bmp.inc'
29
 
30
;;================================================================================================;;
31
;;proc img.is.bmp _data, _length ;////////////////////////////////////////////////////////////////;;
32
img.is.bmp:
33
;;------------------------------------------------------------------------------------------------;;
34
;? Determine if raw data could be decoded (is in BMP format)                                      ;;
35
;;------------------------------------------------------------------------------------------------;;
36
;> _data = raw data as read from file/stream                                                      ;;
37
;> _length = data length                                                                          ;;
38
;;------------------------------------------------------------------------------------------------;;
39
;< eax = false / true                                                                             ;;
40
;;================================================================================================;;
41
; test 1 (length of data): data must contain FileHeader and required fields from InfoHeader
42
	cmp	dword [esp+8], sizeof.bmp.FileHeader + 12
43
	jb	.nope
44
; test 2: signature
45
	mov	eax, [esp+4]
46
	cmp	word [eax], 'BM'
47
	je	.yep
48
 
49
  .nope:
50
	xor	eax, eax
51
	ret	8
52
 
53
  .yep:
54
	xor	eax, eax
55
	inc	eax
56
	ret	8
57
;endp
58
 
59
;;================================================================================================;;
60
proc img.decode.bmp _data, _length, _options ;////////////////////////////////////////////////////;;
61
;;------------------------------------------------------------------------------------------------;;
62
;? Decode data into image if it contains correctly formed raw data in BMP format                  ;;
63
;;------------------------------------------------------------------------------------------------;;
64
;> _data = raw data as read from file/stream                                                      ;;
65
;> _length = data length                                                                          ;;
66
;;------------------------------------------------------------------------------------------------;;
67
;< eax = 0 (error) or pointer to image                                                            ;;
68
;;================================================================================================;;
69
locals
70
  length_rest dd ?
71
  img dd ?
72
  bTopDown db ?
73
  bIsIco db ?
74
endl
75
img.decode.bmp.length_rest equ length_rest
76
	mov	[bIsIco], 0
77
.common: ; common place for BMP and ICO
78
 
79
	push	ebx esi edi
80
 
81
	mov	ebx, [_data]
82
	cmp	[bIsIco], 0
83
	jnz	@f
84
	add	ebx, sizeof.bmp.FileHeader
85
	sub	[_length], sizeof.bmp.FileHeader
86
   @@:
87
 
88
	mov	eax, [ebx + bmp.InfoHeader.Size]
89
; sanity check: file length must be greater than size of headers
90
	cmp	[_length], eax
91
	jbe	.error
92
 
93
	mov	[bTopDown], 0
94
 
95
	cmp	eax, 12		; 0x0C
96
	jz	.old1
97
	cmp	eax, 40		; 0x28
98
	jz	.normal
99
	cmp	eax, 56		; 0x38
100
	je	.normal
101
	cmp	eax, 0x6C
102
	je	.normal
103
	cmp	eax, 0x7C
104
	jnz	.error
105
; convert images with <= 8 bpp to 8bpp, other - to 32 bpp
106
.normal:
107
	m2m	eax, Image.bpp8i
108
	cmp	byte [ebx + 14], 8	; bit count
109
	jbe	@f
110
	mov	al, Image.bpp32
111
@@:
112
	push	eax
113
	mov	eax, [ebx + 8]	;[ebx + bmp.InfoHeader.Height]
114
	test	eax, eax
115
	jns	@f
116
	inc	[bTopDown]
117
	neg	eax
118
@@:
119
	cmp	[bIsIco], 0	; for icons Height is two times larger than image height
120
	jz	@f
121
	shr	eax, 1
122
@@:
123
	pushd	eax
124
	pushd	[ebx + 4]	;[ebx + bmp.InfoHeader.Width]
125
	jmp	.create
126
.old1:
127
	m2m	eax, Image.bpp8i
128
	cmp	byte [ebx + 10], 8	; bit count
129
	jbe	@f
130
	mov	al, Image.bpp32
131
@@:
132
	push	eax
133
	movsx	eax, word [ebx + 6]	;[ebx + bmp.InfoHeader.OldHeight]
134
	test	eax, eax
135
	jns	@f
136
	inc	[bTopDown]
137
	neg	eax
138
@@:
139
	cmp	[bIsIco], 0	; for icons Height is two times larger than image height
140
	jz	@f
141
	shr	eax, 1
142
@@:
143
	push	eax
144
	movzx	eax, word [ebx + 4]	;[ebx + bmp.InfoHeader.OldWidth]
145
	push	eax
146
.create:
147
	call	img.create
148
 
149
	or	eax, eax
150
	jz	.error
151
	mov	[img], eax
152
	mov	edx, eax
153
 
154
	invoke	mem.alloc, sizeof.bmp.Image
155
	or	eax, eax
156
	jz	.error.free
157
	mov	[edx + Image.Extended], eax
158
	push	eax
159
	mov	edi, eax
160
	mov	ecx, sizeof.bmp.Image/4
161
	xor	eax, eax
162
	rep	stosd
163
	pop	edi
164
	push	edi
165
	mov	esi, ebx
166
	mov	ecx, [ebx]	;[ebx + bmp.InfoHeader.Size]
167
	cmp	ecx, 12
168
	jz	.old2
169
	rep	movsb
170
	jmp	.decode
171
.old2:
172
	movsd	; Size
173
	movzx	eax, word [esi]	; OldWidth -> Width
174
	stosd
175
	movsx	eax, word [esi+2]	; OldHeight -> Height
176
	stosd
177
	lodsd	; skip OldWidth+OldHeight
178
	movsd	; Planes+BitCount
179
.decode:
180
 
181
	pop	edi
182
	cmp	[bIsIco], 0
183
	jnz	@f
184
	mov	edi, [_length]
185
	add	edi, sizeof.bmp.FileHeader
186
	mov	esi, [ebx - sizeof.bmp.FileHeader + bmp.FileHeader.OffBits]
187
	jmp	.offset_calculated
188
@@:
189
	xor	esi, esi
190
	mov	cl, byte [edi + bmp.Image.info.BitCount]
191
	cmp	cl, 8
192
	ja	@f
193
	inc	esi
194
	add	cl, 2
195
	shl	esi, cl
196
@@:
197
	add	esi, [edi + bmp.Image.info.Size]
198
	mov	edi, [_length]
199
.offset_calculated:
200
	sub	edi, esi
201
	jbe	.error.free
202
	add	esi, [_data]
203
 
204
	mov	eax, [edx + Image.Extended]
205
	mov	eax, [eax + bmp.Image.info.Compression]
206
	cmp	eax, bmp.BI_RGB
207
	jne	@f
208
	stdcall ._.rgb
209
	jmp	.decoded
210
    @@: cmp	eax, bmp.BI_RLE8
211
	jne	@f
212
	cmp	word [ebx + 14], 8 ;bmp.InfoHeader.BitCount
213
	jnz	.error.free
214
	stdcall ._.rle
215
	jmp	.decoded
216
    @@: cmp	eax, bmp.BI_RLE4
217
	jne	@f
218
	cmp	word [ebx + 14], 4
219
	jnz	.error.free
220
	stdcall ._.rle
221
	jmp	.decoded
222
    @@: cmp	eax, bmp.BI_BITFIELDS
223
	jne	.error.free
224
	stdcall ._.bitfields
225
	jmp	.decoded
226
; BI_JPEG and BI_PNG constants are not valid values for BMP file,
227
; they are intended for WinAPI
228
;    @@: cmp	eax, bmp.BI_JPEG
229
;	jne	@f
230
;	stdcall ._.jpeg
231
;	jmp	.decoded
232
;    @@: cmp	eax, bmp.BI_PNG
233
;	jne	.error
234
;	stdcall ._.png
235
 
236
  .decoded:
237
	or	eax, eax
238
	jz	@f
239
  .error.free:
240
	stdcall img.destroy, [img]
241
	jmp	.error
242
 
243
    @@:
244
	cmp	[bTopDown], 0
245
	jnz	@f
246
	stdcall img.flip, [img], FLIP_VERTICAL
247
    @@:
248
	mov	eax, [img]
249
	mov	ecx, [length_rest]	; return length for ICO code
250
	cmp	[bIsIco], 0
251
	jz	@f
252
	mov	[esp + 4], esi	; return pointer to end-of-data for ICO code
253
    @@:
254
	pop	edi esi ebx
255
	ret
256
 
257
  .error:
258
	xor	eax, eax
259
	pop	edi esi ebx
260
	ret
261
endp
262
 
263
;;================================================================================================;;
264
proc img.encode.bmp _img, _common, _specific ;////////////////////////////////////////////////////;;
265
;;------------------------------------------------------------------------------------------------;;
266
;? Encode image into raw data in BMP format                                                       ;;
267
;;------------------------------------------------------------------------------------------------;;
268
;> [_img]      = pointer to image                                                                 ;;
269
;> [_common]   = format independent options                                                       ;;
270
;> [_specific] = 0 / pointer to the structure of format specific options                          ;;
271
;;------------------------------------------------------------------------------------------------;;
272
;< eax = 0 / pointer to encoded data                                                              ;;
273
;< ecx = error code / the size of encoded data                                                    ;;
274
;;================================================================================================;;
275
locals
276
	bytes_per_scanline	rd 1
277
	encoded_file		rd 1
278
	encoded_file_size	rd 1
279
	encoded_data_size	rd 1
280
endl
281
	mov	ebx, [_img]
282
	mov	eax, [ebx + Image.Type]
283
	cmp	eax, Image.bpp24
284
	je	.bpp24
285
	cmp	eax, Image.bpp32
286
	je	.bpp32
287
	mov	ecx, LIBIMG_ERROR_BIT_DEPTH
288
	jmp	.error
289
 
290
  .bpp24:
291
	mov	eax, [ebx + Image.Width]
292
	call	img._.get_scanline_len
293
	test	eax, 0x03
294
	jz	@f
295
	and	al, 0xfc
296
	add	eax, 4
297
    @@:
298
	mov	[bytes_per_scanline], eax
299
	imul	eax, [ebx + Image.Height]
300
	mov	[encoded_data_size], eax
301
	add	eax, 108 + 14
302
	mov	[encoded_file_size], eax
303
	stdcall	[mem.alloc], eax
304
	test	eax, eax
305
	jz	.error
306
	mov	[encoded_file], eax
307
	mov	edi, eax
308
 
309
	mov	word[edi], 'BM'
310
	add	edi, 2
311
	mov	eax, [encoded_file_size]
312
	stosd
313
	xor	eax, eax
314
	stosd
315
	mov	eax, 108 + 14
316
	stosd
317
	mov	eax, 108
318
	stosd
319
	mov	eax, [ebx + Image.Width]
320
	stosd
321
	mov	eax, [ebx + Image.Height]
322
	stosd
323
	mov	ax, 1	; Planes
324
	stosw
325
	mov	ax, 24	; BitCount
326
	stosw
327
	mov	eax, bmp.BI_RGB
328
	stosd
329
	mov	eax, [encoded_data_size]
330
	stosd
331
	mov	eax, 0x00000B13
332
	stosd
333
	stosd
334
	xor	eax, eax
335
	stosd
336
	stosd
337
	mov	eax, 'BGRs'
338
	stosd
339
	xor	eax, eax
340
	stosd
341
	stosd
342
	stosd
343
	stosd
344
	stosd
345
	stosd
346
	stosd
347
	stosd
348
	stosd
349
	stosd
350
	stosd
351
	stosd
352
	mov	eax, 2
353
	stosd
354
	xor	eax, eax
355
	stosd
356
	stosd
357
	stosd
358
 
359
	mov	esi, [ebx + Image.Data]
360
	mov	ecx, [ebx + Image.Width]
361
	lea	ecx, [ecx*3]
362
	mov	eax, [ebx + Image.Height]
363
	mov	edx, [bytes_per_scanline]
364
	sub	edx, ecx
365
	mov	dh, cl
366
	and	dh, 3
367
	shr	ecx, 2
368
	push	ecx
369
	add	edi, [encoded_data_size]
370
	sub	edi, [bytes_per_scanline]
371
    @@:
372
	pop	ecx
373
	push	ecx
374
	rep	movsd
375
	mov	cl, dh
376
	rep	movsb
377
	mov	cl, dl
378
	add	edi, ecx
379
	sub	edi, [bytes_per_scanline]
380
	sub	edi, [bytes_per_scanline]
381
	dec	eax
382
	jnz	@b
383
	pop	ecx
384
	mov	eax, [encoded_file]
385
	mov	ecx, [encoded_file_size]
386
	jmp	.quit
387
 
388
  .bpp32:
389
	mov	eax, [ebx + Image.Width]
390
	call	img._.get_scanline_len
391
	mov	[bytes_per_scanline], eax
392
	imul	eax, [ebx + Image.Height]
393
	mov	[encoded_data_size], eax
394
	add	eax, 0x7C + 14
395
	mov	[encoded_file_size], eax
396
	stdcall	[mem.alloc], eax
397
	test	eax, eax
398
	jz	.error
399
	mov	[encoded_file], eax
400
	mov	edi, eax
401
 
402
	mov	word[edi], 'BM'
403
	add	edi, 2
404
	mov	eax, [encoded_file_size]
405
	stosd
406
	xor	eax, eax
407
	stosd
408
	mov	eax, 0x7C + 14
409
	stosd
410
	mov	eax, 0x7C
411
	stosd
412
	mov	eax, [ebx + Image.Width]
413
	stosd
414
	mov	eax, [ebx + Image.Height]
415
	stosd
416
	mov	ax, 1	; Planes
417
	stosw
418
	mov	ax, 32	; BitCount
419
	stosw
420
	mov	eax, 3	; WTF? bmp.BI_RGB
421
	stosd
422
	mov	eax, [encoded_data_size]
423
	stosd
424
	mov	eax, 0x00000B13
425
	stosd
426
	stosd
427
	xor	eax, eax
428
	stosd
429
	stosd
430
	mov	eax, 0xFF000000
431
	stosd
432
	shr	eax, 8
433
	stosd
434
	shr	eax, 8
435
	stosd
436
;	shr	eax, 8
437
	xor	eax, eax
438
	stosd
439
	mov	eax, 'BGRs'
440
	stosd
441
	xor	eax, eax
442
	stosd
443
	stosd
444
	stosd
445
	stosd
446
	stosd
447
	stosd
448
	stosd
449
	stosd
450
	stosd
451
	stosd
452
	stosd
453
	stosd
454
	mov	eax, 2
455
	stosd
456
	xor	eax, eax
457
	stosd
458
	stosd
459
	stosd
460
 
461
	mov	esi, [ebx + Image.Data]
462
	mov	ecx, [ebx + Image.Width]
463
	mov	eax, [ebx + Image.Height]
464
	add	edi, [encoded_data_size]
465
	sub	edi, [bytes_per_scanline]
466
	push	ecx
467
  .next_line:
468
	pop	ecx
469
	push	ecx
470
	push	eax
471
    @@:
472
	dec	ecx
473
	js	@f
474
	lodsd
475
	rol	eax, 8
476
	stosd
477
	jmp	@b
478
    @@:
479
	sub	edi, [bytes_per_scanline]
480
	sub	edi, [bytes_per_scanline]
481
	pop	eax
482
	dec	eax
483
	jnz	.next_line
484
	pop	ecx
485
	mov	eax, [encoded_file]
486
	mov	ecx, [encoded_file_size]
487
	jmp	.quit
488
 
489
  .error:
490
	xor	eax, eax
491
  .quit:
492
	ret
493
endp
494
 
495
 
496
;;================================================================================================;;
497
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
498
;;================================================================================================;;
499
;! Below are private procs you should never call directly from your code                          ;;
500
;;================================================================================================;;
501
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
502
;;================================================================================================;;
503
 
504
 
505
;;================================================================================================;;
506
proc img.decode.bmp._.rgb ;///////////////////////////////////////////////////////////////////////;;
507
;;------------------------------------------------------------------------------------------------;;
508
;? --- TBD ---                                                                                    ;;
509
;;------------------------------------------------------------------------------------------------;;
510
;> ebx = raw image data                                                                           ;;
511
;> edx = image data                                                                               ;;
512
;;------------------------------------------------------------------------------------------------;;
513
;< --- TBD ---                                                                                    ;;
514
;;================================================================================================;;
515
	mov	ecx, [edx + Image.Extended]
516
	mov	[ecx + bmp.Image.info.AlphaMask], 0
517
 
518
	movzx	eax, [ecx + bmp.Image.info.BitCount]
519
	cmp	eax, 32
520
	je	.32bpp
521
	cmp	eax, 24
522
	je	.24bpp
523
	cmp	eax, 16
524
	je	.16bpp
525
	cmp	eax, 8
526
	je	.8bpp
527
	cmp	eax, 4
528
	je	.4bpp
529
	cmp	eax, 1
530
	je	.1bpp
531
	jmp	.error
532
 
533
;;------------------------------------------------------------------------------------------------;;
534
 
535
img.decode.bmp._.rgb.32bpp:
536
	mov	[ecx + bmp.Image.info.RedMask],   00000000111111110000000000000000b ; 8-0-0
537
	mov	[ecx + bmp.Image.info.GreenMask], 00000000000000001111111100000000b ; 0-8-0
538
	mov	[ecx + bmp.Image.info.BlueMask],  00000000000000000000000011111111b ; 0-0-8
539
	stdcall img.decode.bmp._.bitfields
540
	ret
541
 
542
;;------------------------------------------------------------------------------------------------;;
543
 
544
img.decode.bmp._.rgb.24bpp:
545
	mov	eax, [edx + Image.Width]
546
	lea	eax, [eax*3 + 3]
547
	and	eax, not 3
548
	mov	ecx, [edx + Image.Height]
549
	imul	eax, ecx
550
	sub	edi, eax
551
	jb	img.decode.bmp._.rgb.error
552
	mov	[img.decode.bmp.length_rest], edi
553
	mov	edi, [edx + Image.Data]
554
 
555
  .next_line:
556
	push	ecx edx
557
	mov	ecx, [edx + Image.Width]
558
	xor	edx, edx
559
 
560
  .next_line_pixel:
561
	movsd
562
	dec	esi
563
	inc	edx
564
	dec	ecx
565
	jnz	.next_line_pixel
566
 
567
	and	edx, 0x03
568
	add	esi, edx
569
	pop	edx ecx
570
	dec	ecx
571
	jnz	.next_line
572
 
573
	jmp	img.decode.bmp._.rgb.exit
574
 
575
;;------------------------------------------------------------------------------------------------;;
576
 
577
img.decode.bmp._.rgb.16bpp:
578
	mov	[ecx + bmp.Image.info.RedMask],   00000000000000000111110000000000b ; 5-0-0
579
	mov	[ecx + bmp.Image.info.GreenMask], 00000000000000000000001111100000b ; 0-5-0
580
	mov	[ecx + bmp.Image.info.BlueMask],  00000000000000000000000000011111b ; 0-0-5
581
	stdcall img.decode.bmp._.bitfields
582
	ret
583
 
584
;;------------------------------------------------------------------------------------------------;;
585
 
586
img.decode.bmp._.rgb.8bpp:
587
	mov	eax, [edx + Image.Width]
588
	add	eax, 3
589
	call	img.decode.bmp._.rgb.prepare_palette
590
	jc	img.decode.bmp._.rgb.error
591
 
592
  .next_line:
593
	push	ecx
594
	mov	ecx, [edx + Image.Width]
595
	mov	eax, ecx
596
	neg	eax
597
	and	eax, 3
598
	rep	movsb
599
	add	esi, eax
600
	pop	ecx
601
	dec	ecx
602
	jnz	.next_line
603
 
604
	jmp	img.decode.bmp._.rgb.exit
605
 
606
;;------------------------------------------------------------------------------------------------;;
607
 
608
img.decode.bmp._.rgb.4bpp:
609
	mov	eax, [edx + Image.Width]
610
	add	eax, 7
611
	shr	eax, 1
612
	call	img.decode.bmp._.rgb.prepare_palette
613
	jc	img.decode.bmp._.rgb.error
614
 
615
  .next_line:
616
	push	ecx edx
617
	mov	ecx, [edx + Image.Width]
618
 
619
  .next_line_dword:
620
	push	ecx
621
	lodsd
622
	bswap	eax
623
	xchg	edx, eax
624
	mov	ecx, 32 / 4
625
 
626
  .next_pixel:
627
	rol	edx, 4
628
	mov	al, dl
629
	and	al, 0x0000000F
630
	stosb
631
	dec	dword[esp]
632
	jz	@f
633
	dec	ecx
634
	jnz	.next_pixel
635
 
636
    @@: pop	ecx
637
	or	ecx, ecx
638
	jnz	.next_line_dword
639
 
640
	pop	edx ecx
641
	dec	ecx
642
	jnz	.next_line
643
 
644
	jmp	img.decode.bmp._.rgb.exit
645
 
646
;;------------------------------------------------------------------------------------------------;;
647
 
648
img.decode.bmp._.rgb.1bpp:
649
	mov	eax, [edx + Image.Width]
650
	add	eax, 31
651
	shr	eax, 3
652
	call	img.decode.bmp._.rgb.prepare_palette
653
	jc	img.decode.bmp._.rgb.error
654
 
655
  .next_line:
656
	push	ecx edx
657
	mov	ecx, [edx + Image.Width]
658
 
659
  .next_line_dword:
660
	push	ecx
661
	lodsd
662
	bswap	eax
663
	xchg	edx, eax
664
	mov	ecx, 32 / 1
665
 
666
  .next_pixel:
667
	rol	edx, 1
668
	mov	al, dl
669
	and	al, 0x00000001
670
	stosb
671
	dec	dword[esp]
672
	jz	@f
673
	dec	ecx
674
	jnz	.next_pixel
675
 
676
    @@: pop	ecx
677
	or	ecx, ecx
678
	jnz	.next_line_dword
679
 
680
	pop	edx ecx
681
	dec	ecx
682
	jnz	.next_line
683
 
684
	jmp	img.decode.bmp._.rgb.exit
685
 
686
;;------------------------------------------------------------------------------------------------;;
687
 
688
  img.decode.bmp._.rgb.exit:
689
	xor	eax, eax
690
	ret
691
 
692
  img.decode.bmp._.rgb.error:
693
	or	eax, -1
694
	ret
695
 
696
img.decode.bmp._.rgb.prepare_palette:
697
	and	eax, not 3
698
	mov	ecx, [edx + Image.Height]
699
	imul	eax, ecx
700
	sub	edi, eax
701
	jb	.ret
702
	mov	[img.decode.bmp.length_rest], edi
703
	push	esi
704
	sub	esi, ebx
705
	jc	.ret.pop
706
	sub	esi, [ebx + bmp.InfoHeader.Size]
707
	jc	.ret.pop
708
	mov	eax, esi
709
	mov	edi, [edx + Image.Palette]
710
	push	ecx
711
	mov	ecx, 256
712
	mov	esi, [ebx + bmp.InfoHeader.Size]
713
	cmp	esi, 12
714
	jz	.old
715
	shr	eax, 2
716
	add	esi, ebx
717
	cmp	ecx, eax
718
	jb	@f
719
	mov	ecx, eax
720
@@:
721
	rep	movsd
722
	jmp	.common
723
.old:
724
	add	esi, ebx
725
@@:
726
	movsd
727
	dec	esi
728
	sub	eax, 3
729
	jbe	@f
730
	sub	ecx, 1
731
	jnz	@b
732
@@:
733
.common:
734
	pop	ecx
735
	mov	edi, [edx + Image.Data]
736
	clc
737
.ret.pop:
738
	pop	esi
739
.ret:
740
	ret
741
endp
742
 
743
;;================================================================================================;;
744
proc img.decode.bmp._.rle ;///////////////////////////////////////////////////////////////////////;;
745
;;------------------------------------------------------------------------------------------------;;
746
;? --- TBD ---                                                                                    ;;
747
;;------------------------------------------------------------------------------------------------;;
748
;> ebx = raw image data                                                                           ;;
749
;> edx = image data                                                                               ;;
750
;;------------------------------------------------------------------------------------------------;;
751
;< --- TBD ---                                                                                    ;;
752
;;================================================================================================;;
753
locals
754
  scanline_len	dd ?
755
  marker_x	dd ?
756
  marker_y	dd ?
757
  abs_mode_addr dd ?
758
  enc_mode_addr dd ?
759
  height	dd ?
760
endl
761
 
762
	mov	[abs_mode_addr], .absolute_mode.rle8
763
	mov	[enc_mode_addr], .encoded_mode.rle8
764
	cmp	[ebx + bmp.InfoHeader.Compression], bmp.BI_RLE4
765
	jne	@f
766
	mov	[abs_mode_addr], .absolute_mode.rle4
767
	mov	[enc_mode_addr], .encoded_mode.rle4
768
    @@:
769
 
770
	push	edi
771
	xor	eax, eax	; do not check file size in .prepare_palette
772
	push	ebp
773
	mov	ebp, [ebp]	; set parent stack frame
774
	call	img.decode.bmp._.rgb.prepare_palette
775
	pop	ebp
776
	pop	ecx	; ecx = rest bytes in file
777
	jc	.error
778
 
779
	mov	eax, [edx + Image.Width]
780
	mov	[scanline_len], eax
781
	mov	eax, [edx + Image.Height]
782
	mov	[height], eax
783
	xor	eax, eax
784
	mov	[marker_x], eax
785
	mov	[marker_y], eax
786
	mov	edi, [edx + Image.Data]
787
 
788
  .next_run:
789
	sub	ecx, 1
790
	jc	.eof
791
	xor	eax, eax
792
	lodsb
793
	or	al, al
794
	jz	.escape_mode
795
	jmp	[enc_mode_addr]
796
 
797
  .escape_mode:
798
	sub	ecx, 1
799
	jc	.eof
800
	lodsb
801
	cmp	al, 0
802
	je	.end_of_scanline
803
	cmp	al, 1
804
	je	.exit
805
	cmp	al, 2
806
	je	.offset_marker
807
	jmp	[abs_mode_addr]
808
 
809
  .end_of_scanline: ; 0
810
	sub	edi, [marker_x]
811
	add	edi, [scanline_len]
812
	mov	[marker_x], 0
813
	mov	eax, [marker_y]
814
	inc	eax
815
	mov	[marker_y], eax
816
	cmp	eax, [height]
817
	jb	.next_run
818
	jmp	.exit
819
 
820
  .offset_marker: ; 2: dx, dy
821
	sub	ecx, 2
822
	jc	.eof
823
	lodsb
824
	mov	edx, [marker_x]
825
	add	edx, eax
826
	cmp	edx, [scanline_len]
827
	jae	.exit
828
	mov	[marker_x], edx
829
	add	edi, eax
830
	lodsb
831
	mov	edx, [marker_y]
832
	add	edx, eax
833
	cmp	edx, [height]
834
	jae	.exit
835
	mov	[marker_y], edx
836
	imul	eax, [scanline_len]
837
	add	edi, eax
838
	jmp	.next_run
839
 
840
  .encoded_mode.rle8: ; N: b1 * N
841
	call	.fix_marker
842
	sub	ecx, 1
843
	jc	.eof
844
	lodsb
845
	push	ecx
846
	mov	ecx, edx
847
	rep	stosb
848
	pop	ecx
849
	jmp	.check_eoi
850
 
851
  .absolute_mode.rle8: ; N: b1 .. bN
852
	call	.fix_marker
853
	cmp	ecx, edx
854
	jae	@f
855
	mov	edx, ecx
856
    @@:
857
	push	ecx
858
	mov	ecx, edx
859
	rep	movsb
860
	pop	ecx
861
	sub	ecx, edx
862
	jz	.eof
863
	test	edx, 1
864
	jz	.check_eoi
865
	sub	ecx, 1
866
	jc	.eof
867
	inc	esi
868
  .check_eoi:
869
	mov	eax, [marker_y]
870
	cmp	eax, [height]
871
	jb	.next_run
872
	jmp	.exit
873
 
874
  .encoded_mode.rle4: ; N: b1 * N
875
	call	.fix_marker
876
	sub	ecx, 1
877
	jc	.eof
878
	movzx	eax, byte [esi]
879
	inc	esi
880
	push	ecx
881
	mov	ecx, eax
882
	and	eax, 0xF
883
	shr	ecx, 4
884
    @@:
885
	dec	edx
886
	js	@f
887
	mov	[edi], cl
888
	dec	edx
889
	js	@f
890
	mov	[edi+1], al
891
	add	edi, 2
892
	jmp	@b
893
    @@:
894
	pop	ecx
895
	jmp	.check_eoi
896
 
897
  .absolute_mode.rle4: ; N: b1 .. bN
898
	call	.fix_marker
899
	lea	eax, [edx+1]
900
	shr	eax, 1
901
	cmp	ecx, eax
902
	jbe	@f
903
	lea	edx, [ecx*2]
904
    @@:
905
	push	ecx edx
906
    @@: dec	edx
907
	js	@f
908
	lodsb
909
	mov	cl, al
910
	shr	al, 4
911
	and	cl, 0xF
912
	stosb
913
	dec	edx
914
	js	@f
915
	mov	[edi], cl
916
	inc	edi
917
	jmp	@b
918
    @@: pop	eax ecx
919
	and	eax, 0x03
920
	jp	.check_eoi
921
	sub	ecx, 1
922
	jc	.eof
923
	inc	esi
924
	jmp	.check_eoi
925
 
926
  .fix_marker:
927
	mov	edx, eax
928
	add	eax, [marker_x]
929
	mov	[marker_x], eax
930
    @@:
931
	sub	eax, [scanline_len]
932
	jle	@f
933
	mov	[marker_x], eax
934
	push	eax
935
	mov	eax, [marker_y]
936
	inc	eax
937
	mov	[marker_y], eax
938
	cmp	eax, [height]
939
	pop	eax
940
	jb	@b
941
	sub	edx, eax
942
    @@:
943
        retn
944
 
945
  .exit:
946
  .eof:
947
	xor	eax, eax
948
	ret
949
 
950
  .error:
951
	or	eax, -1
952
	ret
953
endp
954
 
955
;;================================================================================================;;
956
proc img.decode.bmp._.bitfields ;/////////////////////////////////////////////////////////////////;;
957
;;------------------------------------------------------------------------------------------------;;
958
;? --- TBD ---                                                                                    ;;
959
;;------------------------------------------------------------------------------------------------;;
960
;> ebx = raw image data                                                                           ;;
961
;> edx = image data                                                                               ;;
962
;;------------------------------------------------------------------------------------------------;;
963
;< --- TBD ---                                                                                    ;;
964
;;================================================================================================;;
965
locals
966
  shift   bmp.RgbByteQuad
967
  unshift bmp.RgbByteQuad
968
  mask	  bmp.RgbQuad
969
  delta   dd ?
970
  dataoff dd ?	; offset of encoded data
971
		; row data are aligned on dword from data start, not file start
972
endl
973
 
974
	mov	[delta], 4
975
	mov	eax, [edx + Image.Extended]
976
	cmp	[eax + bmp.Image.info.BitCount], 32
977
	je	@f
978
	cmp	[eax + bmp.Image.info.BitCount], 16
979
	jne	.error
980
	mov	[delta], 2
981
    @@:
982
	mov	ecx, [edx + Image.Width]
983
	imul	ecx, [edx + Image.Height]
984
	imul	ecx, [delta]
985
	sub	edi, ecx
986
	jb	.error
987
	mov	ecx, [ebp]	; use parent stack frame
988
	mov	[ecx + img.decode.bmp.length_rest - ebp], edi	; !
989
 
990
	push	esi
991
	mov	esi, eax
992
 
993
	mov	ecx, [esi + bmp.Image.info.RedMask]
994
	call	.calc_shift
995
	mov	[shift.Red], al
996
	mov	[mask.Red], ecx
997
	call	.calc_unshift
998
	mov	[unshift.Red], al
999
	mov	ecx, [esi + bmp.Image.info.GreenMask]
1000
	call	.calc_shift
1001
	mov	[shift.Green], al
1002
	mov	[unshift.Green], al
1003
	mov	[mask.Green], ecx
1004
	call	.calc_unshift
1005
	mov	[unshift.Green], al
1006
	mov	ecx, [esi + bmp.Image.info.BlueMask]
1007
	call	.calc_shift
1008
	mov	[shift.Blue], al
1009
	mov	[unshift.Blue], al
1010
	mov	[mask.Blue], ecx
1011
	call	.calc_unshift
1012
	mov	[unshift.Blue], al
1013
	mov	ecx, [esi + bmp.Image.info.AlphaMask]
1014
	call	.calc_shift
1015
	mov	[shift.Alpha], al
1016
	mov	[unshift.Alpha], al
1017
	mov	[mask.Alpha], ecx
1018
	call	.calc_unshift
1019
	mov	[unshift.Alpha], al
1020
 
1021
	mov	edi, [edx + Image.Data]
1022
	pop	esi
1023
	mov	[dataoff], esi
1024
 
1025
;;------------------------------------------------------------------------------------------------;;
1026
 
1027
	mov	ecx, [edx + Image.Height]
1028
 
1029
  .next_line:
1030
	push	ecx
1031
	mov	ecx, [edx + Image.Width]
1032
 
1033
  .next_pixel:
1034
	push	ecx
1035
 
1036
	mov	eax, [esi]
1037
	mov	cl, [shift.Blue]
1038
	shr	eax, cl
1039
	and	eax, [mask.Blue]
1040
	mov	cl, [unshift.Blue]
1041
	shl	eax, cl
1042
	stosb
1043
 
1044
	mov	eax, [esi]
1045
	mov	cl, [shift.Green]
1046
	shr	eax, cl
1047
	and	eax, [mask.Green]
1048
	mov	cl, [unshift.Green]
1049
	shl	eax, cl
1050
	stosb
1051
 
1052
	mov	eax, [esi]
1053
	mov	cl, [shift.Red]
1054
	shr	eax, cl
1055
	and	eax, [mask.Red]
1056
	mov	cl, [unshift.Red]
1057
	shl	eax, cl
1058
	stosb
1059
 
1060
	mov	eax, [esi]
1061
	mov	cl, [shift.Alpha]
1062
	shr	eax, cl
1063
	and	eax, [mask.Alpha]
1064
	mov	cl, [unshift.Alpha]
1065
	shl	eax, cl
1066
	stosb
1067
 
1068
	add	esi, [delta]
1069
 
1070
	pop	ecx
1071
	dec	ecx
1072
	jnz	.next_pixel
1073
 
1074
	sub	esi, [dataoff]
1075
	add	esi, 3
1076
	and	esi, not 3
1077
	add	esi, [dataoff]
1078
	pop	ecx
1079
	dec	ecx
1080
	jnz	.next_line
1081
 
1082
;;------------------------------------------------------------------------------------------------;;
1083
 
1084
  .exit:
1085
	xor	eax, eax
1086
	pop	edi
1087
	ret
1088
 
1089
  .error:
1090
	or	eax, -1
1091
	pop	edi
1092
	ret
1093
 
1094
.calc_shift:
1095
	xor	eax, eax
1096
	or	ecx, ecx
1097
	jnz	@f
1098
	retn
1099
    @@: test	ecx, 1
1100
	jnz	@f
1101
   .zz: shr	ecx, 1
1102
	inc	eax
1103
	jmp	@b
1104
    @@: test	ecx, 0100000000b
1105
	jnz	.zz
1106
	retn
1107
.calc_unshift:
1108
	xor	eax, eax
1109
	or	ecx, ecx
1110
	jnz	@f
1111
	retn
1112
    @@: test	ecx, 1
1113
	jz	@f
1114
	shr	ecx, 1
1115
	inc	eax
1116
	jmp	@b
1117
    @@: sub	eax, 8
1118
	neg	eax
1119
	retn
1120
endp
1121
 
1122
if 0
1123
;;================================================================================================;;
1124
proc img.decode.bmp._.jpeg ;//////////////////////////////////////////////////////////////////////;;
1125
;;------------------------------------------------------------------------------------------------;;
1126
;? --- TBD ---                                                                                    ;;
1127
;;------------------------------------------------------------------------------------------------;;
1128
;> ebx = raw image data                                                                           ;;
1129
;> edx = image data                                                                               ;;
1130
;;------------------------------------------------------------------------------------------------;;
1131
;< --- TBD ---                                                                                    ;;
1132
;;================================================================================================;;
1133
	xor	eax, eax
1134
	ret
1135
endp
1136
 
1137
;;================================================================================================;;
1138
proc img.decode.bmp._.png ;///////////////////////////////////////////////////////////////////////;;
1139
;;------------------------------------------------------------------------------------------------;;
1140
;? --- TBD ---                                                                                    ;;
1141
;;------------------------------------------------------------------------------------------------;;
1142
;> ebx = raw image data                                                                           ;;
1143
;> edx = image data                                                                               ;;
1144
;;------------------------------------------------------------------------------------------------;;
1145
;< --- TBD ---                                                                                    ;;
1146
;;================================================================================================;;
1147
	xor	eax, eax
1148
	ret
1149
endp
1150
end if
1151
 
1152
;;================================================================================================;;
1153
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1154
;;================================================================================================;;
1155
;! Below is private data you should never use directly from your code                             ;;
1156
;;================================================================================================;;
1157
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1158
;;================================================================================================;;
1159
 
1160
 
1161
;