Subversion Repositories Kolibri OS

Rev

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