Subversion Repositories Kolibri OS

Rev

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