Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
717 mikedld 1
;;================================================================================================;;
999 diamond 2
;;//// bmp.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ///////////////////////////////////;;
717 mikedld 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 ;;
999 diamond 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.                                         ;;
717 mikedld 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  ;;
999 diamond 13
;; Lesser General Public License for more details.                                                ;;
717 mikedld 14
;;                                                                                                ;;
999 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
717 mikedld 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
;;================================================================================================;;
999 diamond 31
;;proc img.is.bmp _data, _length ;////////////////////////////////////////////////////////////////;;
32
img.is.bmp:
717 mikedld 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
;;================================================================================================;;
999 diamond 41
; test 1 (length of data): data must contain FileHeader and required fields from InfoHeader
42
	cmp	dword [esp+8], sizeof.bmp.FileHeader + 12
717 mikedld 43
	jb	.nope
999 diamond 44
; test 2: signature
45
	mov	eax, [esp+4]
46
	cmp	word [eax], 'BM'
717 mikedld 47
	je	.yep
48
 
49
  .nope:
50
	xor	eax, eax
999 diamond 51
	ret	8
717 mikedld 52
 
53
  .yep:
999 diamond 54
	xor	eax, eax
717 mikedld 55
	inc	eax
999 diamond 56
	ret	8
57
;endp
717 mikedld 58
 
59
;;================================================================================================;;
60
proc img.decode.bmp _data, _length ;//////////////////////////////////////////////////////////////;;
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
  img dd ?
999 diamond 71
  bTopDown db ?
717 mikedld 72
endl
73
 
999 diamond 74
	push	ebx esi edi
717 mikedld 75
 
999 diamond 76
; img.is.bmp has been already called by img.decode
77
;	stdcall img.is.bmp, [_data], [_length]
78
;	or	eax, eax
79
;	jz	.error
717 mikedld 80
 
81
	mov	ebx, [_data]
82
;       cmp     [ebx + bmp.Header.info.Compression], bmp.BI_RGB
83
;       je      @f
84
;       mov     eax, [ebx + bmp.Header.file.Size]
85
;       cmp     eax, [_length]
86
;       jne     .error
999 diamond 87
;   @@:
717 mikedld 88
 
999 diamond 89
	mov	eax, [ebx + bmp.Header.info.Size]
90
; sanity check: file length must be greater than size of headers
91
	add	eax, sizeof.bmp.FileHeader
92
	cmp	[_length], eax
93
	jbe	.error
94
 
95
	mov	[bTopDown], 0
96
 
97
	cmp	eax, sizeof.bmp.FileHeader + 12
98
	jz	.old1
99
	cmp	eax, sizeof.bmp.FileHeader + 40
100
	jz	.normal
101
	cmp	eax, sizeof.bmp.FileHeader + 56
102
	jnz	.error
103
; convert images with <= 8 bpp to 8bpp, other - to 32 bpp
104
.normal:
1079 diamond 105
	m2m	eax, Image.bpp8
999 diamond 106
	cmp	[ebx + bmp.Header.info.BitCount], 8
107
	jbe	@f
108
	mov	al, Image.bpp32
109
@@:
110
	push	eax
111
	mov	eax, [ebx + bmp.Header.info.Height]
112
	test	eax, eax
113
	jns	@f
114
	inc	[bTopDown]
115
	neg	eax
116
@@:
117
	pushd	eax
118
	pushd	[ebx + bmp.Header.info.Width]
119
	jmp	.create
120
.old1:
1079 diamond 121
	m2m	eax, Image.bpp8
999 diamond 122
	cmp	[ebx + bmp.Header.info.OldBitCount], 8
123
	jbe	@f
124
	mov	al, Image.bpp32
125
@@:
126
	push	eax
127
	movsx	eax, [ebx + bmp.Header.info.OldHeight]
128
	test	eax, eax
129
	jns	@f
130
	inc	[bTopDown]
131
	neg	eax
132
@@:
133
	push	eax
134
	movzx	eax, [ebx + bmp.Header.info.OldWidth]
135
	push	eax
136
.create:
137
	call	img.create
138
 
717 mikedld 139
	or	eax, eax
140
	jz	.error
141
	mov	[img], eax
142
	mov	edx, eax
143
 
144
	invoke	mem.alloc, sizeof.bmp.Image
145
	or	eax, eax
999 diamond 146
	jz	.error.free
717 mikedld 147
	mov	[edx + Image.Extended], eax
999 diamond 148
	push	eax
717 mikedld 149
	mov	edi, eax
999 diamond 150
	mov	ecx, sizeof.bmp.Image/4
151
	xor	eax, eax
152
	rep	stosd
153
	pop	edi
154
	lea	esi, [ebx + sizeof.bmp.FileHeader]
155
	pushd	[ebx + bmp.FileHeader.OffBits]
156
	mov	ecx, [esi + bmp.InfoHeader.Size]
157
	cmp	ecx, 12
158
	jz	.old2
717 mikedld 159
	rep	movsb
999 diamond 160
	jmp	.decode
161
.old2:
162
	movsd	; Size
163
	movzx	eax, word [esi]	; OldWidth -> Width
164
	stosd
165
	movsx	eax, word [esi+2]	; OldHeight -> Height
166
	stosd
167
	lodsd	; skip OldWidth+OldHeight
168
	movsd	; Planes+BitCount
169
.decode:
717 mikedld 170
 
999 diamond 171
	pop	eax
172
	mov	esi, [_length]
173
	sub	esi, eax
174
	jbe	.error.free
175
 
176
	mov	eax, [edx + Image.Extended]
177
	mov	eax, [eax + bmp.Image.info.Compression]
717 mikedld 178
	cmp	eax, bmp.BI_RGB
179
	jne	@f
180
	stdcall ._.rgb
181
	jmp	.decoded
182
    @@: cmp	eax, bmp.BI_RLE8
183
	jne	@f
999 diamond 184
	cmp	[ebx + bmp.Header.info.BitCount], 8
185
	jnz	.error.free
717 mikedld 186
	stdcall ._.rle
187
	jmp	.decoded
188
    @@: cmp	eax, bmp.BI_RLE4
189
	jne	@f
999 diamond 190
	cmp	[ebx + bmp.Header.info.BitCount], 4
191
	jnz	.error.free
717 mikedld 192
	stdcall ._.rle
193
	jmp	.decoded
194
    @@: cmp	eax, bmp.BI_BITFIELDS
999 diamond 195
	jne	.error.free
717 mikedld 196
	stdcall ._.bitfields
197
	jmp	.decoded
999 diamond 198
; BI_JPEG and BI_PNG constants are not valid values for BMP file,
199
; they are intended for WinAPI
200
;    @@: cmp	eax, bmp.BI_JPEG
201
;	jne	@f
202
;	stdcall ._.jpeg
203
;	jmp	.decoded
204
;    @@: cmp	eax, bmp.BI_PNG
205
;	jne	.error
206
;	stdcall ._.png
717 mikedld 207
 
208
  .decoded:
209
	or	eax, eax
210
	jz	@f
999 diamond 211
  .error.free:
717 mikedld 212
	stdcall img.destroy, [img]
213
	jmp	.error
999 diamond 214
 
215
    @@:
216
	cmp	[bTopDown], 0
217
	jnz	@f
218
	stdcall img.flip, [img], FLIP_VERTICAL
219
    @@:
717 mikedld 220
	mov	eax, [img]
999 diamond 221
	pop	edi esi ebx
717 mikedld 222
	ret
223
 
224
  .error:
225
	xor	eax, eax
999 diamond 226
	pop	edi esi ebx
717 mikedld 227
	ret
228
endp
229
 
230
;;================================================================================================;;
231
proc img.encode.bmp _img, _p_length ;/////////////////////////////////////////////////////////////;;
232
;;------------------------------------------------------------------------------------------------;;
233
;? Encode image into raw data in BMP format                                                       ;;
234
;;------------------------------------------------------------------------------------------------;;
235
;> _img = pointer to image                                                                        ;;
236
;;------------------------------------------------------------------------------------------------;;
237
;< eax = 0 (error) or pointer to encoded data                                                     ;;
238
;< _p_length = encoded data length                                                                ;;
239
;;================================================================================================;;
240
	xor	eax, eax
241
	ret
242
endp
243
 
244
 
245
;;================================================================================================;;
246
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
247
;;================================================================================================;;
248
;! Below are private procs you should never call directly from your code                          ;;
249
;;================================================================================================;;
250
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
251
;;================================================================================================;;
252
 
253
 
254
;;================================================================================================;;
255
proc img.decode.bmp._.rgb ;///////////////////////////////////////////////////////////////////////;;
256
;;------------------------------------------------------------------------------------------------;;
257
;? --- TBD ---                                                                                    ;;
258
;;------------------------------------------------------------------------------------------------;;
259
;> ebx = raw image data                                                                           ;;
260
;> edx = image data                                                                               ;;
261
;;------------------------------------------------------------------------------------------------;;
262
;< --- TBD ---                                                                                    ;;
263
;;================================================================================================;;
264
	mov	ecx, [edx + Image.Extended]
265
	mov	[ecx + bmp.Image.info.AlphaMask], 0
266
	mov	edi, [edx + Image.Data]
267
 
999 diamond 268
	movzx	eax, [ecx + bmp.Image.info.BitCount]
717 mikedld 269
	cmp	eax, 32
270
	je	.32bpp
271
	cmp	eax, 24
272
	je	.24bpp
273
	cmp	eax, 16
274
	je	.16bpp
275
	cmp	eax, 8
276
	je	.8bpp
277
	cmp	eax, 4
278
	je	.4bpp
279
	cmp	eax, 1
280
	je	.1bpp
281
	jmp	.error
282
 
283
;;------------------------------------------------------------------------------------------------;;
284
 
285
img.decode.bmp._.rgb.32bpp:
286
	mov	[ecx + bmp.Image.info.RedMask],   00000000111111110000000000000000b ; 8-0-0
287
	mov	[ecx + bmp.Image.info.GreenMask], 00000000000000001111111100000000b ; 0-8-0
288
	mov	[ecx + bmp.Image.info.BlueMask],  00000000000000000000000011111111b ; 0-0-8
289
	stdcall img.decode.bmp._.bitfields
290
	ret
291
 
292
;;------------------------------------------------------------------------------------------------;;
293
 
294
img.decode.bmp._.rgb.24bpp:
999 diamond 295
	mov	eax, [edx + Image.Width]
296
	lea	eax, [eax*3 + 3]
297
	and	eax, not 3
298
	mov	ecx, [edx + Image.Height]
299
	imul	eax, ecx
300
	cmp	esi, eax
301
	jb	img.decode.bmp._.rgb.error
717 mikedld 302
	mov	esi, ebx
303
	add	esi, [ebx + bmp.Header.file.OffBits]
304
 
305
  .next_line:
999 diamond 306
	push	ecx edx
307
	mov	ecx, [edx + Image.Width]
717 mikedld 308
	xor	edx, edx
309
 
310
  .next_line_pixel:
311
	movsd
312
	dec	esi
313
	inc	edx
314
	dec	ecx
315
	jnz	.next_line_pixel
316
 
317
	and	edx, 0x03
318
	add	esi, edx
999 diamond 319
	pop	edx ecx
717 mikedld 320
	dec	ecx
321
	jnz	.next_line
322
 
323
	jmp	img.decode.bmp._.rgb.exit
324
 
325
;;------------------------------------------------------------------------------------------------;;
326
 
327
img.decode.bmp._.rgb.16bpp:
328
	mov	[ecx + bmp.Image.info.RedMask],   00000000000000000111110000000000b ; 5-0-0
329
	mov	[ecx + bmp.Image.info.GreenMask], 00000000000000000000001111100000b ; 0-5-0
330
	mov	[ecx + bmp.Image.info.BlueMask],  00000000000000000000000000011111b ; 0-0-5
331
	stdcall img.decode.bmp._.bitfields
332
	ret
333
 
334
;;------------------------------------------------------------------------------------------------;;
335
 
336
img.decode.bmp._.rgb.8bpp:
999 diamond 337
	mov	eax, [edx + Image.Width]
338
	add	eax, 3
339
	call	img.decode.bmp._.rgb.prepare_palette
340
	jc	img.decode.bmp._.rgb.error
717 mikedld 341
 
342
  .next_line:
343
	push	ecx
999 diamond 344
	mov	ecx, [edx + Image.Width]
345
	mov	eax, ecx
346
	neg	eax
347
	and	eax, 3
348
	rep	movsb
349
	add	esi, eax
717 mikedld 350
	pop	ecx
351
	dec	ecx
352
	jnz	.next_line
353
 
354
	jmp	img.decode.bmp._.rgb.exit
355
 
356
;;------------------------------------------------------------------------------------------------;;
357
 
358
img.decode.bmp._.rgb.4bpp:
999 diamond 359
	mov	eax, [edx + Image.Width]
360
	add	eax, 7
361
	shr	eax, 1
362
	call	img.decode.bmp._.rgb.prepare_palette
363
	jc	img.decode.bmp._.rgb.error
717 mikedld 364
 
365
  .next_line:
999 diamond 366
	push	ecx edx
367
	mov	ecx, [edx + Image.Width]
717 mikedld 368
 
369
  .next_line_dword:
370
	push	ecx
371
	lodsd
372
	bswap	eax
373
	xchg	edx, eax
374
	mov	ecx, 32 / 4
375
 
376
  .next_pixel:
377
	rol	edx, 4
378
	mov	al, dl
999 diamond 379
	and	al, 0x0000000F
380
	stosb
717 mikedld 381
	dec	dword[esp]
382
	jz	@f
383
	dec	ecx
384
	jnz	.next_pixel
385
 
386
    @@: pop	ecx
387
	or	ecx, ecx
388
	jnz	.next_line_dword
389
 
999 diamond 390
	pop	edx ecx
717 mikedld 391
	dec	ecx
392
	jnz	.next_line
393
 
394
	jmp	img.decode.bmp._.rgb.exit
395
 
396
;;------------------------------------------------------------------------------------------------;;
397
 
398
img.decode.bmp._.rgb.1bpp:
999 diamond 399
	mov	eax, [edx + Image.Width]
400
	add	eax, 31
401
	shr	eax, 3
402
	call	img.decode.bmp._.rgb.prepare_palette
403
	jc	img.decode.bmp._.rgb.error
717 mikedld 404
 
405
  .next_line:
999 diamond 406
	push	ecx edx
407
	mov	ecx, [edx + Image.Width]
717 mikedld 408
 
409
  .next_line_dword:
410
	push	ecx
411
	lodsd
412
	bswap	eax
413
	xchg	edx, eax
414
	mov	ecx, 32 / 1
415
 
416
  .next_pixel:
417
	rol	edx, 1
418
	mov	al, dl
999 diamond 419
	and	al, 0x00000001
420
	stosb
717 mikedld 421
	dec	dword[esp]
422
	jz	@f
423
	dec	ecx
424
	jnz	.next_pixel
425
 
426
    @@: pop	ecx
427
	or	ecx, ecx
428
	jnz	.next_line_dword
429
 
999 diamond 430
	pop	edx ecx
717 mikedld 431
	dec	ecx
432
	jnz	.next_line
433
 
434
	jmp	img.decode.bmp._.rgb.exit
435
 
436
;;------------------------------------------------------------------------------------------------;;
437
 
438
  img.decode.bmp._.rgb.exit:
439
	xor	eax, eax
440
	ret
441
 
442
  img.decode.bmp._.rgb.error:
443
	or	eax, -1
444
	ret
999 diamond 445
 
446
img.decode.bmp._.rgb.prepare_palette:
447
	and	eax, not 3
448
	mov	ecx, [edx + Image.Height]
449
	imul	eax, ecx
450
	cmp	esi, eax
451
	jb	.ret
452
	mov	esi, [ebx + bmp.Header.info.Size]
453
	add	esi, sizeof.bmp.FileHeader
454
	jc	.ret
455
	mov	eax, [ebx + bmp.Header.file.OffBits]
456
	sub	eax, esi
457
	jc	.ret
458
	push	edi
459
	mov	edi, [edx + Image.Palette]
460
	push	ecx
461
	mov	ecx, 256
462
	cmp	esi, sizeof.bmp.FileHeader + 12
463
	jz	.old
464
	shr	eax, 2
465
	add	esi, ebx
466
	cmp	ecx, eax
467
	jb	@f
468
	mov	ecx, eax
469
@@:
470
	rep	movsd
471
	jmp	.common
472
.old:
473
	movsd
474
	dec	esi
475
	sub	eax, 3
476
	jbe	@f
477
	sub	ecx, 1
478
	jnz	.old
479
@@:
480
.common:
481
	pop	ecx
482
	pop	edi
483
	mov	esi, ebx
484
	add	esi, [ebx + bmp.Header.file.OffBits]
485
.ret:
486
	ret
717 mikedld 487
endp
488
 
489
;;================================================================================================;;
490
proc img.decode.bmp._.rle ;///////////////////////////////////////////////////////////////////////;;
491
;;------------------------------------------------------------------------------------------------;;
492
;? --- TBD ---                                                                                    ;;
493
;;------------------------------------------------------------------------------------------------;;
494
;> ebx = raw image data                                                                           ;;
495
;> edx = image data                                                                               ;;
496
;;------------------------------------------------------------------------------------------------;;
497
;< --- TBD ---                                                                                    ;;
498
;;================================================================================================;;
499
locals
500
  scanline_len	dd ?
501
  marker_x	dd ?
502
  marker_y	dd ?
503
  abs_mode_addr dd ?
504
  enc_mode_addr dd ?
999 diamond 505
  height	dd ?
717 mikedld 506
endl
507
 
508
	mov	[abs_mode_addr], .absolute_mode.rle8
509
	mov	[enc_mode_addr], .encoded_mode.rle8
510
	cmp	[ebx + bmp.Header.info.Compression], bmp.BI_RLE4
511
	jne	@f
512
	mov	[abs_mode_addr], .absolute_mode.rle4
513
	mov	[enc_mode_addr], .encoded_mode.rle4
999 diamond 514
    @@:
717 mikedld 515
 
999 diamond 516
	push	esi
517
	xor	eax, eax	; do not check file size in .prepare_palette
518
	call	img.decode.bmp._.rgb.prepare_palette
519
	pop	ecx	; ecx = rest bytes in file
520
	jc	.error
521
 
717 mikedld 522
	mov	eax, [edx + Image.Width]
523
	mov	[scanline_len], eax
999 diamond 524
	mov	eax, [edx + Image.Height]
525
	mov	[height], eax
717 mikedld 526
	xor	eax, eax
527
	mov	[marker_x], eax
528
	mov	[marker_y], eax
999 diamond 529
	mov	edi, [edx + Image.Data]
717 mikedld 530
 
531
  .next_run:
999 diamond 532
	sub	ecx, 1
533
	jc	.eof
717 mikedld 534
	xor	eax, eax
535
	lodsb
536
	or	al, al
537
	jz	.escape_mode
538
	jmp	[enc_mode_addr]
539
 
540
  .escape_mode:
999 diamond 541
	sub	ecx, 1
542
	jc	.eof
717 mikedld 543
	lodsb
544
	cmp	al, 0
545
	je	.end_of_scanline
546
	cmp	al, 1
547
	je	.exit
548
	cmp	al, 2
549
	je	.offset_marker
550
	jmp	[abs_mode_addr]
551
 
552
  .end_of_scanline: ; 0
999 diamond 553
	sub	edi, [marker_x]
554
	add	edi, [scanline_len]
717 mikedld 555
	mov	[marker_x], 0
999 diamond 556
	mov	eax, [marker_y]
557
	inc	eax
558
	mov	[marker_y], eax
559
	cmp	eax, [height]
560
	jb	.next_run
561
	jmp	.exit
717 mikedld 562
 
563
  .offset_marker: ; 2: dx, dy
999 diamond 564
	sub	ecx, 2
565
	jc	.eof
717 mikedld 566
	lodsb
567
	mov	edx, [marker_x]
568
	add	edx, eax
999 diamond 569
	cmp	edx, [scanline_len]
717 mikedld 570
	jae	.exit
571
	mov	[marker_x], edx
572
	add	edi, eax
573
	lodsb
574
	mov	edx, [marker_y]
575
	add	edx, eax
999 diamond 576
	cmp	edx, [height]
717 mikedld 577
	jae	.exit
578
	mov	[marker_y], edx
579
	imul	eax, [scanline_len]
580
	add	edi, eax
581
	jmp	.next_run
582
 
583
  .encoded_mode.rle8: ; N: b1 * N
999 diamond 584
	call	.fix_marker
585
	sub	ecx, 1
586
	jc	.eof
717 mikedld 587
	lodsb
999 diamond 588
	push	ecx
589
	mov	ecx, edx
590
	rep	stosb
591
	pop	ecx
592
	jmp	.check_eoi
717 mikedld 593
 
594
  .absolute_mode.rle8: ; N: b1 .. bN
999 diamond 595
	call	.fix_marker
596
	cmp	ecx, edx
597
	jae	@f
598
	mov	edx, ecx
599
    @@:
600
	push	ecx
601
	mov	ecx, edx
602
	rep	movsb
603
	pop	ecx
604
	sub	ecx, edx
605
	jz	.eof
606
	test	edx, 1
607
	jz	.check_eoi
608
	sub	ecx, 1
609
	jc	.eof
717 mikedld 610
	inc	esi
999 diamond 611
  .check_eoi:
612
	mov	eax, [marker_y]
613
	cmp	eax, [height]
614
	jb	.next_run
615
	jmp	.exit
717 mikedld 616
 
617
  .encoded_mode.rle4: ; N: b1 * N
999 diamond 618
	call	.fix_marker
619
	sub	ecx, 1
620
	jc	.eof
621
	movzx	eax, byte [esi]
622
	inc	esi
623
	push	ecx
717 mikedld 624
	mov	ecx, eax
999 diamond 625
	and	eax, 0xF
717 mikedld 626
	shr	ecx, 4
999 diamond 627
    @@:
628
	dec	edx
629
	js	@f
630
	mov	[edi], cl
631
	dec	edx
632
	js	@f
633
	mov	[edi+1], al
634
	add	edi, 2
717 mikedld 635
	jmp	@b
999 diamond 636
    @@:
637
	pop	ecx
638
	jmp	.check_eoi
717 mikedld 639
 
640
  .absolute_mode.rle4: ; N: b1 .. bN
999 diamond 641
	call	.fix_marker
642
	lea	eax, [edx+1]
643
	shr	eax, 1
644
	cmp	ecx, eax
645
	jbe	@f
646
	lea	edx, [ecx*2]
647
    @@:
648
	push	ecx edx
717 mikedld 649
    @@: dec	edx
650
	js	@f
651
	lodsb
999 diamond 652
	mov	cl, al
653
	shr	al, 4
654
	and	cl, 0xF
655
	stosb
717 mikedld 656
	dec	edx
657
	js	@f
999 diamond 658
	mov	[edi], cl
659
	inc	edi
717 mikedld 660
	jmp	@b
999 diamond 661
    @@: pop	eax ecx
717 mikedld 662
	and	eax, 0x03
999 diamond 663
	jp	.check_eoi
664
	sub	ecx, 1
665
	jc	.eof
717 mikedld 666
	inc	esi
999 diamond 667
	jmp	.check_eoi
717 mikedld 668
 
669
  .fix_marker:
999 diamond 670
	mov	edx, eax
671
	add	eax, [marker_x]
717 mikedld 672
	mov	[marker_x], eax
999 diamond 673
    @@:
674
	sub	eax, [scanline_len]
675
	jle	@f
676
	mov	[marker_x], eax
677
	push	eax
678
	mov	eax, [marker_y]
679
	inc	eax
680
	mov	[marker_y], eax
681
	cmp	eax, [height]
682
	pop	eax
683
	jb	@b
684
	sub	edx, eax
685
    @@:
686
        retn
717 mikedld 687
 
688
  .exit:
999 diamond 689
  .eof:
717 mikedld 690
	xor	eax, eax
691
	ret
692
 
693
  .error:
694
	or	eax, -1
695
	ret
696
endp
697
 
698
;;================================================================================================;;
699
proc img.decode.bmp._.bitfields ;/////////////////////////////////////////////////////////////////;;
700
;;------------------------------------------------------------------------------------------------;;
701
;? --- TBD ---                                                                                    ;;
702
;;------------------------------------------------------------------------------------------------;;
703
;> ebx = raw image data                                                                           ;;
704
;> edx = image data                                                                               ;;
705
;;------------------------------------------------------------------------------------------------;;
706
;< --- TBD ---                                                                                    ;;
707
;;================================================================================================;;
708
locals
709
  shift   bmp.RgbByteQuad
710
  unshift bmp.RgbByteQuad
711
  mask	  bmp.RgbQuad
712
  delta   dd ?
713
endl
714
 
999 diamond 715
	push	edi
717 mikedld 716
 
999 diamond 717
	mov	[delta], 4
718
	mov	eax, [edx + Image.Extended]
719
	cmp	[eax + bmp.Image.info.BitCount], 32
720
	je	@f
721
	cmp	[eax + bmp.Image.info.BitCount], 16
722
	jne	.error
723
	mov	[delta], 2
724
    @@:
725
	mov	ecx, [edx + Image.Width]
726
	imul	ecx, [edx + Image.Height]
727
	imul	ecx, [delta]
728
	cmp	esi, ecx
729
	jb	.error
730
 
731
	mov	esi, eax
732
 
717 mikedld 733
	mov	ecx, [esi + bmp.Image.info.RedMask]
734
	call	.calc_shift
735
	mov	[shift.Red], al
736
	mov	[mask.Red], ecx
737
	call	.calc_unshift
738
	mov	[unshift.Red], al
739
	mov	ecx, [esi + bmp.Image.info.GreenMask]
740
	call	.calc_shift
741
	mov	[shift.Green], al
742
	mov	[unshift.Green], al
743
	mov	[mask.Green], ecx
744
	call	.calc_unshift
745
	mov	[unshift.Green], al
746
	mov	ecx, [esi + bmp.Image.info.BlueMask]
747
	call	.calc_shift
748
	mov	[shift.Blue], al
749
	mov	[unshift.Blue], al
750
	mov	[mask.Blue], ecx
751
	call	.calc_unshift
752
	mov	[unshift.Blue], al
753
	mov	ecx, [esi + bmp.Image.info.AlphaMask]
754
	call	.calc_shift
755
	mov	[shift.Alpha], al
756
	mov	[unshift.Alpha], al
757
	mov	[mask.Alpha], ecx
758
	call	.calc_unshift
759
	mov	[unshift.Alpha], al
760
 
761
	mov	edi, [edx + Image.Data]
762
	mov	esi, ebx
763
	add	esi, [ebx + bmp.Header.file.OffBits]
764
 
765
;;------------------------------------------------------------------------------------------------;;
766
 
999 diamond 767
	mov	ecx, [edx + Image.Height]
717 mikedld 768
 
769
  .next_line:
770
	push	ecx
771
	mov	ecx, [edx + Image.Width]
772
 
773
  .next_pixel:
774
	push	ecx
775
 
776
	mov	eax, [esi]
777
	mov	cl, [shift.Blue]
778
	shr	eax, cl
779
	and	eax, [mask.Blue]
780
	mov	cl, [unshift.Blue]
781
	shl	eax, cl
782
	stosb
783
 
784
	mov	eax, [esi]
785
	mov	cl, [shift.Green]
786
	shr	eax, cl
787
	and	eax, [mask.Green]
788
	mov	cl, [unshift.Green]
789
	shl	eax, cl
790
	stosb
791
 
792
	mov	eax, [esi]
793
	mov	cl, [shift.Red]
794
	shr	eax, cl
795
	and	eax, [mask.Red]
796
	mov	cl, [unshift.Red]
797
	shl	eax, cl
798
	stosb
799
 
800
	mov	eax, [esi]
801
	mov	cl, [shift.Alpha]
802
	shr	eax, cl
803
	and	eax, [mask.Alpha]
804
	mov	cl, [unshift.Alpha]
805
	shl	eax, cl
806
	stosb
807
 
808
	add	esi, [delta]
809
 
810
	pop	ecx
811
	dec	ecx
812
	jnz	.next_pixel
813
 
814
	pop	ecx
815
	dec	ecx
816
	jnz	.next_line
817
 
818
;;------------------------------------------------------------------------------------------------;;
819
 
820
  .exit:
821
	xor	eax, eax
999 diamond 822
	pop	edi
717 mikedld 823
	ret
824
 
825
  .error:
826
	or	eax, -1
999 diamond 827
	pop	edi
717 mikedld 828
	ret
829
 
830
.calc_shift:
831
	xor	eax, eax
832
	or	ecx, ecx
833
	jnz	@f
834
	retn
835
    @@: test	ecx, 1
836
	jnz	@f
837
   .zz: shr	ecx, 1
838
	inc	eax
839
	jmp	@b
840
    @@: test	ecx, 0100000000b
841
	jnz	.zz
842
	retn
843
.calc_unshift:
844
	xor	eax, eax
845
	or	ecx, ecx
846
	jnz	@f
847
	retn
848
    @@: test	ecx, 1
849
	jz	@f
850
	shr	ecx, 1
851
	inc	eax
852
	jmp	@b
853
    @@: sub	eax, 8
854
	neg	eax
855
	retn
856
endp
857
 
999 diamond 858
if 0
717 mikedld 859
;;================================================================================================;;
860
proc img.decode.bmp._.jpeg ;//////////////////////////////////////////////////////////////////////;;
861
;;------------------------------------------------------------------------------------------------;;
862
;? --- TBD ---                                                                                    ;;
863
;;------------------------------------------------------------------------------------------------;;
864
;> ebx = raw image data                                                                           ;;
865
;> edx = image data                                                                               ;;
866
;;------------------------------------------------------------------------------------------------;;
867
;< --- TBD ---                                                                                    ;;
868
;;================================================================================================;;
869
	xor	eax, eax
870
	ret
871
endp
872
 
873
;;================================================================================================;;
874
proc img.decode.bmp._.png ;///////////////////////////////////////////////////////////////////////;;
875
;;------------------------------------------------------------------------------------------------;;
876
;? --- TBD ---                                                                                    ;;
877
;;------------------------------------------------------------------------------------------------;;
878
;> ebx = raw image data                                                                           ;;
879
;> edx = image data                                                                               ;;
880
;;------------------------------------------------------------------------------------------------;;
881
;< --- TBD ---                                                                                    ;;
882
;;================================================================================================;;
883
	xor	eax, eax
884
	ret
885
endp
999 diamond 886
end if
717 mikedld 887
 
888
;;================================================================================================;;
889
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
890
;;================================================================================================;;
891
;! Below is private data you should never use directly from your code                             ;;
892
;;================================================================================================;;
893
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
894
;;================================================================================================;;
895
 
896
 
897
;