Subversion Repositories Kolibri OS

Rev

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