Subversion Repositories Kolibri OS

Rev

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