Subversion Repositories Kolibri OS

Rev

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