Subversion Repositories Kolibri OS

Rev

Rev 1102 | Rev 2692 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;================================================================================================;;
  2. ;;//// bmp.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009 ///////////////////////////////////;;
  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 ;;
  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.                                         ;;
  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  ;;
  13. ;; Lesser General Public License for more details.                                                ;;
  14. ;;                                                                                                ;;
  15. ;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
  16. ;; If not, see <http://www.gnu.org/licenses/>.                                                    ;;
  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. ;;================================================================================================;;
  31. ;;proc img.is.bmp _data, _length ;////////////////////////////////////////////////////////////////;;
  32. img.is.bmp:
  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. ;;================================================================================================;;
  41. ; test 1 (length of data): data must contain FileHeader and required fields from InfoHeader
  42.         cmp     dword [esp+8], sizeof.bmp.FileHeader + 12
  43.         jb      .nope
  44. ; test 2: signature
  45.         mov     eax, [esp+4]
  46.         cmp     word [eax], 'BM'
  47.         je      .yep
  48.  
  49.   .nope:
  50.         xor     eax, eax
  51.         ret     8
  52.  
  53.   .yep:
  54.         xor     eax, eax
  55.         inc     eax
  56.         ret     8
  57. ;endp
  58.  
  59. ;;================================================================================================;;
  60. proc img.decode.bmp _data, _length, _options ;////////////////////////////////////////////////////;;
  61. ;;------------------------------------------------------------------------------------------------;;
  62. ;? Decode data into image if it contains correctly formed raw data in BMP format                  ;;
  63. ;;------------------------------------------------------------------------------------------------;;
  64. ;> _data = raw data as read from file/stream                                                      ;;
  65. ;> _length = data length                                                                          ;;
  66. ;;------------------------------------------------------------------------------------------------;;
  67. ;< eax = 0 (error) or pointer to image                                                            ;;
  68. ;;================================================================================================;;
  69. locals
  70.   length_rest dd ?
  71.   img dd ?
  72.   bTopDown db ?
  73.   bIsIco db ?
  74. endl
  75. img.decode.bmp.length_rest equ length_rest
  76.         mov     [bIsIco], 0
  77. .common: ; common place for BMP and ICO
  78.  
  79.         push    ebx esi edi
  80.  
  81.         mov     ebx, [_data]
  82.         cmp     [bIsIco], 0
  83.         jnz     @f
  84.         add     ebx, sizeof.bmp.FileHeader
  85.         sub     [_length], sizeof.bmp.FileHeader
  86.    @@:
  87.  
  88.         mov     eax, [ebx + bmp.InfoHeader.Size]
  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.  
  95.         cmp     eax, 12         ; 0x0C
  96.         jz      .old1
  97.         cmp     eax, 40         ; 0x28
  98.         jz      .normal
  99.         cmp     eax, 56         ; 0x38
  100.         je      .normal
  101.         cmp     eax, 108        ; 0x6C
  102.         jnz     .error
  103. ; convert images with <= 8 bpp to 8bpp, other - to 32 bpp
  104. .normal:
  105.         m2m     eax, Image.bpp8
  106.         cmp     byte [ebx + 14], 8      ; bit count
  107.         jbe     @f
  108.         mov     al, Image.bpp32
  109. @@:
  110.         push    eax
  111.         mov     eax, [ebx + 8]  ;[ebx + bmp.InfoHeader.Height]
  112.         test    eax, eax
  113.         jns     @f
  114.         inc     [bTopDown]
  115.         neg     eax
  116. @@:
  117.         cmp     [bIsIco], 0     ; for icons Height is two times larger than image height
  118.         jz      @f
  119.         shr     eax, 1
  120. @@:
  121.         pushd   eax
  122.         pushd   [ebx + 4]       ;[ebx + bmp.InfoHeader.Width]
  123.         jmp     .create
  124. .old1:
  125.         m2m     eax, Image.bpp8
  126.         cmp     byte [ebx + 10], 8      ; bit count
  127.         jbe     @f
  128.         mov     al, Image.bpp32
  129. @@:
  130.         push    eax
  131.         movsx   eax, word [ebx + 6]     ;[ebx + bmp.InfoHeader.OldHeight]
  132.         test    eax, eax
  133.         jns     @f
  134.         inc     [bTopDown]
  135.         neg     eax
  136. @@:
  137.         cmp     [bIsIco], 0     ; for icons Height is two times larger than image height
  138.         jz      @f
  139.         shr     eax, 1
  140. @@:
  141.         push    eax
  142.         movzx   eax, word [ebx + 4]     ;[ebx + bmp.InfoHeader.OldWidth]
  143.         push    eax
  144. .create:
  145.         call    img.create
  146.  
  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
  154.         jz      .error.free
  155.         mov     [edx + Image.Extended], eax
  156.         push    eax
  157.         mov     edi, eax
  158.         mov     ecx, sizeof.bmp.Image/4
  159.         xor     eax, eax
  160.         rep     stosd
  161.         pop     edi
  162.         push    edi
  163.         mov     esi, ebx
  164.         mov     ecx, [ebx]      ;[ebx + bmp.InfoHeader.Size]
  165.         cmp     ecx, 12
  166.         jz      .old2
  167.         rep     movsb
  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:
  178.  
  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
  199.         jbe     .error.free
  200.         add     esi, [_data]
  201.  
  202.         mov     eax, [edx + Image.Extended]
  203.         mov     eax, [eax + bmp.Image.info.Compression]
  204.         cmp     eax, bmp.BI_RGB
  205.         jne     @f
  206.         stdcall ._.rgb
  207.         jmp     .decoded
  208.     @@: cmp     eax, bmp.BI_RLE8
  209.         jne     @f
  210.         cmp     word [ebx + 14], 8 ;bmp.InfoHeader.BitCount
  211.         jnz     .error.free
  212.         stdcall ._.rle
  213.         jmp     .decoded
  214.     @@: cmp     eax, bmp.BI_RLE4
  215.         jne     @f
  216.         cmp     word [ebx + 14], 4
  217.         jnz     .error.free
  218.         stdcall ._.rle
  219.         jmp     .decoded
  220.     @@: cmp     eax, bmp.BI_BITFIELDS
  221.         jne     .error.free
  222.         stdcall ._.bitfields
  223.         jmp     .decoded
  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
  233.  
  234.   .decoded:
  235.         or      eax, eax
  236.         jz      @f
  237.   .error.free:
  238.         stdcall img.destroy, [img]
  239.         jmp     .error
  240.  
  241.     @@:
  242.         cmp     [bTopDown], 0
  243.         jnz     @f
  244.         stdcall img.flip, [img], FLIP_VERTICAL
  245.     @@:
  246.         mov     eax, [img]
  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.     @@:
  252.         pop     edi esi ebx
  253.         ret
  254.  
  255.   .error:
  256.         xor     eax, eax
  257.         pop     edi esi ebx
  258.         ret
  259. endp
  260.  
  261. ;;================================================================================================;;
  262. proc img.encode.bmp _img, _p_length, _options ;///////////////////////////////////////////////////;;
  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.  
  298.         movzx   eax, [ecx + bmp.Image.info.BitCount]
  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:
  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
  330.         sub     edi, eax
  331.         jb      img.decode.bmp._.rgb.error
  332.         mov     [img.decode.bmp.length_rest], edi
  333.         mov     edi, [edx + Image.Data]
  334.  
  335.   .next_line:
  336.         push    ecx edx
  337.         mov     ecx, [edx + Image.Width]
  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
  349.         pop     edx ecx
  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:
  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
  371.  
  372.   .next_line:
  373.         push    ecx
  374.         mov     ecx, [edx + Image.Width]
  375.         mov     eax, ecx
  376.         neg     eax
  377.         and     eax, 3
  378.         rep     movsb
  379.         add     esi, eax
  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:
  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
  394.  
  395.   .next_line:
  396.         push    ecx edx
  397.         mov     ecx, [edx + Image.Width]
  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
  409.         and     al, 0x0000000F
  410.         stosb
  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.  
  420.         pop     edx ecx
  421.         dec     ecx
  422.         jnz     .next_line
  423.  
  424.         jmp     img.decode.bmp._.rgb.exit
  425.  
  426. ;;------------------------------------------------------------------------------------------------;;
  427.  
  428. img.decode.bmp._.rgb.1bpp:
  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
  434.  
  435.   .next_line:
  436.         push    ecx edx
  437.         mov     ecx, [edx + Image.Width]
  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
  449.         and     al, 0x00000001
  450.         stosb
  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.  
  460.         pop     edx ecx
  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
  475.  
  476. img.decode.bmp._.rgb.prepare_palette:
  477.         and     eax, not 3
  478.         mov     ecx, [edx + Image.Height]
  479.         imul    eax, ecx
  480.         sub     edi, eax
  481.         jb      .ret
  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
  489.         mov     edi, [edx + Image.Palette]
  490.         push    ecx
  491.         mov     ecx, 256
  492.         mov     esi, [ebx + bmp.InfoHeader.Size]
  493.         cmp     esi, 12
  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:
  504.         add     esi, ebx
  505. @@:
  506.         movsd
  507.         dec     esi
  508.         sub     eax, 3
  509.         jbe     @f
  510.         sub     ecx, 1
  511.         jnz     @b
  512. @@:
  513. .common:
  514.         pop     ecx
  515.         mov     edi, [edx + Image.Data]
  516.         clc
  517. .ret.pop:
  518.         pop     esi
  519. .ret:
  520.         ret
  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 ?
  539.   height        dd ?
  540. endl
  541.  
  542.         mov     [abs_mode_addr], .absolute_mode.rle8
  543.         mov     [enc_mode_addr], .encoded_mode.rle8
  544.         cmp     [ebx + bmp.InfoHeader.Compression], bmp.BI_RLE4
  545.         jne     @f
  546.         mov     [abs_mode_addr], .absolute_mode.rle4
  547.         mov     [enc_mode_addr], .encoded_mode.rle4
  548.     @@:
  549.  
  550.         push    edi
  551.         xor     eax, eax        ; do not check file size in .prepare_palette
  552.         push    ebp
  553.         mov     ebp, [ebp]      ; set parent stack frame
  554.         call    img.decode.bmp._.rgb.prepare_palette
  555.         pop     ebp
  556.         pop     ecx     ; ecx = rest bytes in file
  557.         jc      .error
  558.  
  559.         mov     eax, [edx + Image.Width]
  560.         mov     [scanline_len], eax
  561.         mov     eax, [edx + Image.Height]
  562.         mov     [height], eax
  563.         xor     eax, eax
  564.         mov     [marker_x], eax
  565.         mov     [marker_y], eax
  566.         mov     edi, [edx + Image.Data]
  567.  
  568.   .next_run:
  569.         sub     ecx, 1
  570.         jc      .eof
  571.         xor     eax, eax
  572.         lodsb
  573.         or      al, al
  574.         jz      .escape_mode
  575.         jmp     [enc_mode_addr]
  576.  
  577.   .escape_mode:
  578.         sub     ecx, 1
  579.         jc      .eof
  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
  590.         sub     edi, [marker_x]
  591.         add     edi, [scanline_len]
  592.         mov     [marker_x], 0
  593.         mov     eax, [marker_y]
  594.         inc     eax
  595.         mov     [marker_y], eax
  596.         cmp     eax, [height]
  597.         jb      .next_run
  598.         jmp     .exit
  599.  
  600.   .offset_marker: ; 2: dx, dy
  601.         sub     ecx, 2
  602.         jc      .eof
  603.         lodsb
  604.         mov     edx, [marker_x]
  605.         add     edx, eax
  606.         cmp     edx, [scanline_len]
  607.         jae     .exit
  608.         mov     [marker_x], edx
  609.         add     edi, eax
  610.         lodsb
  611.         mov     edx, [marker_y]
  612.         add     edx, eax
  613.         cmp     edx, [height]
  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
  621.         call    .fix_marker
  622.         sub     ecx, 1
  623.         jc      .eof
  624.         lodsb
  625.         push    ecx
  626.         mov     ecx, edx
  627.         rep     stosb
  628.         pop     ecx
  629.         jmp     .check_eoi
  630.  
  631.   .absolute_mode.rle8: ; N: b1 .. bN
  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
  647.         inc     esi
  648.   .check_eoi:
  649.         mov     eax, [marker_y]
  650.         cmp     eax, [height]
  651.         jb      .next_run
  652.         jmp     .exit
  653.  
  654.   .encoded_mode.rle4: ; N: b1 * N
  655.         call    .fix_marker
  656.         sub     ecx, 1
  657.         jc      .eof
  658.         movzx   eax, byte [esi]
  659.         inc     esi
  660.         push    ecx
  661.         mov     ecx, eax
  662.         and     eax, 0xF
  663.         shr     ecx, 4
  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
  672.         jmp     @b
  673.     @@:
  674.         pop     ecx
  675.         jmp     .check_eoi
  676.  
  677.   .absolute_mode.rle4: ; N: b1 .. bN
  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
  686.     @@: dec     edx
  687.         js      @f
  688.         lodsb
  689.         mov     cl, al
  690.         shr     al, 4
  691.         and     cl, 0xF
  692.         stosb
  693.         dec     edx
  694.         js      @f
  695.         mov     [edi], cl
  696.         inc     edi
  697.         jmp     @b
  698.     @@: pop     eax ecx
  699.         and     eax, 0x03
  700.         jp      .check_eoi
  701.         sub     ecx, 1
  702.         jc      .eof
  703.         inc     esi
  704.         jmp     .check_eoi
  705.  
  706.   .fix_marker:
  707.         mov     edx, eax
  708.         add     eax, [marker_x]
  709.         mov     [marker_x], eax
  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
  724.  
  725.   .exit:
  726.   .eof:
  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.  
  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]
  763.         sub     edi, ecx
  764.         jb      .error
  765.         mov     ecx, [ebp]      ; use parent stack frame
  766.         mov     [ecx + img.decode.bmp.length_rest - ebp], edi   ; !
  767.  
  768.         push    esi
  769.         mov     esi, eax
  770.  
  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]
  800.         pop     esi
  801.  
  802. ;;------------------------------------------------------------------------------------------------;;
  803.  
  804.         mov     ecx, [edx + Image.Height]
  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
  859.         pop     edi
  860.         ret
  861.  
  862.   .error:
  863.         or      eax, -1
  864.         pop     edi
  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.  
  895. if 0
  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
  923. end if
  924.  
  925. ;;================================================================================================;;
  926. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  927. ;;================================================================================================;;
  928. ;! Below is private data you should never use directly from your code                             ;;
  929. ;;================================================================================================;;
  930. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  931. ;;================================================================================================;;
  932.  
  933.  
  934. ;
  935.