Subversion Repositories Kolibri OS

Rev

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