Subversion Repositories Kolibri OS

Rev

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