Subversion Repositories Kolibri OS

Rev

Rev 8394 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;================================================================================================;;
  2. ;;//// gif.asm //// (c) mike.dld, 2007-2008 //////////////////////////////////////////////////////;;
  3. ;;================================================================================================;;
  4. ;;//// Partial (c) by Willow, Diamond and HidnPlayr //////////////////////////////////////////////;;
  5. ;;================================================================================================;;
  6. ;;                                                                                                ;;
  7. ;; This file is part of Common development libraries (Libs-Dev).                                  ;;
  8. ;;                                                                                                ;;
  9. ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
  10. ;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
  11. ;; of the License, or (at your option) any later version.                                         ;;
  12. ;;                                                                                                ;;
  13. ;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
  14. ;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
  15. ;; Lesser General Public License for more details.                                                ;;
  16. ;;                                                                                                ;;
  17. ;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
  18. ;; If not, see <http://www.gnu.org/licenses/>.                                                    ;;
  19. ;;                                                                                                ;;
  20. ;;================================================================================================;;
  21. ;;                                                                                                ;;
  22. ;; References:                                                                                    ;;
  23. ;;   1. GIF LITE v3.0 (2004-2007)                                                                 ;;
  24. ;;      by Willow and Diamond                                                                     ;;
  25. ;;      svn://kolibrios.org/programs/media/gifview/trunk/gif_lite.inc                             ;;
  26. ;;   2. "GIF File Format Summary"                                                                 ;;
  27. ;;      from "Encyclopedia of Graphics File Formats" by O'Reilly                                  ;;
  28. ;;      http://www.fileformat.info/format/gif/                                                    ;;
  29. ;;   3. "LZW and GIF explained" (1987)                                                            ;;
  30. ;;      by Steve Blackstock, IEEE                                                                 ;;
  31. ;;      http://www.cis.udel.edu/~amer/CISC651/lzw.and.gif.explained.html                          ;;
  32. ;;   4. "Graphics Interchange Format (tm)" (June 15, 1987)                                        ;;
  33. ;;      by CompuServe Incorporated                                                                ;;
  34. ;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF87A.TXT         ;;
  35. ;;   5. "Graphics Interchange Format (sm)" (July 31, 1990)                                        ;;
  36. ;;      by CompuServe Incorporated                                                                ;;
  37. ;;      http://examples.oreilly.de/english_examples/gff/CDROM/GFF/VENDSPEC/GIF/GIF89A.TXT         ;;
  38. ;;                                                                                                ;;
  39. ;;================================================================================================;;
  40.  
  41.  
  42. include 'gif.inc'
  43.  
  44. ;;================================================================================================;;
  45. proc img.is.gif _data, _length ;//////////////////////////////////////////////////////////////////;;
  46. ;;------------------------------------------------------------------------------------------------;;
  47. ;? Determine if raw data could be decoded (is in GIF format)                                      ;;
  48. ;;------------------------------------------------------------------------------------------------;;
  49. ;> _data = raw data as read from file/stream                                                      ;;
  50. ;> _length = data length                                                                          ;;
  51. ;;------------------------------------------------------------------------------------------------;;
  52. ;< eax = false / true                                                                             ;;
  53. ;;================================================================================================;;
  54.         cmp     [_length], sizeof.gif.Header
  55.         jb      .nope
  56.         mov     eax, [_data]
  57.         cmp     dword[eax], 'GIF8'
  58.         jne     .nope
  59.         cmp     word[eax + 4], '7a'
  60.         je      .yep
  61.         cmp     word[eax + 4], '9a'
  62.         je      .yep
  63.  
  64.   .nope:
  65.         xor     eax, eax
  66.         ret
  67.  
  68.   .yep:
  69.         xor     eax, eax
  70.         inc     eax
  71.         ret
  72. endp
  73.  
  74. ;;================================================================================================;;
  75. proc img.decode.gif _data, _length, _options ;////////////////////////////////////////////////////;;
  76. ;;------------------------------------------------------------------------------------------------;;
  77. ;? Decode data into image if it contains correctly formed raw data in GIF format                  ;;
  78. ;;------------------------------------------------------------------------------------------------;;
  79. ;> _data = raw data as read from file/stream                                                      ;;
  80. ;> _length = data length                                                                          ;;
  81. ;;------------------------------------------------------------------------------------------------;;
  82. ;< eax = 0 (error) or pointer to image                                                            ;;
  83. ;;================================================================================================;;
  84. locals
  85.   max_color          dd ?
  86.   cur_color_table_size dd ?
  87.   transparent_color  dd ?
  88.   background_color   dd ?
  89.   options_bgr        dd ?
  90.   prev_palette       dd ?
  91.   aux_palette        dd ?
  92.   img                dd ?
  93.   prev_img_data      dd ?
  94.   aux_img_data       dd ?
  95.   aux_img_type       dd ?
  96.   prev_num_colors    dd ?
  97.   main_img           dd ?
  98.   global_color_table dd ?
  99.   global_color_table_size dd ?
  100. endl
  101.  
  102. img.decode.gif.main_img equ main_img
  103. img.decode.gif.prev_img_data equ prev_img_data
  104. img.decode.gif.transparent_color equ transparent_color
  105. img.decode.gif.background_color equ background_color
  106. img.decode.gif._length equ _length
  107. img.decode.gif.prev_num_colors equ prev_num_colors
  108. img.decode.gif.prev_palette equ prev_palette
  109. img.decode.gif.max_color equ max_color
  110. img.decode.gif._data equ _data
  111. img.decode.gif.aux_img_data equ aux_img_data
  112. img.decode.gif.aux_img_type equ aux_img_type
  113. img.decode.gif.aux_palette equ aux_palette
  114. img.decode.gif.options_bgr equ options_bgr
  115. ; offset of _length parameter for child functions with ebp-based frame
  116. ; child saved ebp, return address, 3 saved registers, 15 local variables
  117. img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*15
  118. img.decode.gif.max_color_child equ ebp + 4 + 4 + 4*3
  119. img.decode.gif.cur_color_table_size_child equ ebp + 4 + 4 + 4*3 + 4
  120.  
  121.         push    ebx esi edi
  122.         xor     eax, eax
  123.         mov     [img], eax
  124.         mov     [main_img], eax
  125.         mov     [prev_img_data], eax
  126.         mov     [aux_img_data], eax
  127.         mov     [aux_img_type], eax
  128.         mov     [prev_palette], eax
  129.         mov     [aux_palette], eax
  130. ; when no previous image is available, use background fill with 1-entry palette
  131.         inc     eax
  132.         mov     [prev_num_colors], eax
  133.         lea     eax, [background_color]
  134.         mov     [prev_palette], eax
  135. ; value for bgr color in transparent images
  136.         mov     edx, 0xFFFFFF   ; white bgr if no value given
  137.         mov     ecx, [_options]
  138.         jecxz   @f
  139.         cmp     [ecx + ImageDecodeOptions.UsedSize], ImageDecodeOptions.BackgroundColor + 4
  140.         jb      @f
  141.         mov     edx, [ecx + ImageDecodeOptions.BackgroundColor]
  142. @@:
  143.         mov     [options_bgr], edx
  144.         mov     dword [eax], edx
  145. ; guard against incorrect gif files without any color tables
  146. ; "If no color table is available at
  147. ; all, the decoder is free to use a system color table or a table of its own. In
  148. ; that case, the decoder may use a color table with as many colors as its
  149. ; hardware is able to support; it is recommended that such a table have black and
  150. ; white as its first two entries, so that monochrome images can be rendered
  151. ; adequately." (c) official gif documentation
  152.         mov     [global_color_table], gif_default_palette
  153.         mov     [global_color_table_size], 2
  154.  
  155. ; img.is.gif is called by caller (img.decode)
  156. ;       stdcall img.is.gif, [_data], [_length]
  157. ;       or      eax, eax
  158. ;       jz      .error
  159.  
  160.         mov     ebx, [_data]
  161.         sub     [_length], sizeof.gif.Header
  162.  
  163.         mov     cl, [ebx + gif.Header.lsd.Packed]
  164.         add     ebx, sizeof.gif.Header
  165. ; gif.LSD.Packed.GlobalColorTableFlag = 80h
  166. ;       test    cl, gif.LSD.Packed.GlobalColorTableFlag
  167. ;       jz      @f
  168.         test    cl, cl
  169.         jns     @f
  170.         mov     [global_color_table], ebx
  171.         and     cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
  172. ;       shr     cl, gif.LSD.Packed.SizeOfGlobalColorTableShift  ; here Shift = 0
  173.         push    2
  174.         pop     eax
  175.         shl     eax, cl
  176.         mov     [global_color_table_size], eax
  177.         lea     eax, [eax * 3]
  178.         sub     [_length], eax
  179.         jbe     .error  ; there must be at least 1 additional byte after color table
  180.         movzx   ecx, byte [ebx - sizeof.gif.Header + gif.Header.lsd.BackgroundColor]
  181.         lea     ecx, [ecx*3]
  182.         mov     ecx, [ebx + ecx]        ; eax = xxBBGGRR, convert to Kolibri color
  183.         bswap   ecx
  184.         shr     ecx, 8
  185.         mov     [background_color], ecx
  186.         add     ebx, eax
  187.     @@:
  188.  
  189. ;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
  190. ;       jne     .next_image
  191. ;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
  192. ;       jne     .error
  193. ;       add     ebx, sizeof.gif.Extension
  194. ;       stdcall ._.skip_data
  195. ;       mov     ebx, eax
  196. ;       jmp     @b
  197.  
  198.   .next_image:
  199.         stdcall img._.new
  200.         or      eax, eax
  201.         jz      .error
  202.         mov     edx, [img]
  203.         mov     [eax + Image.Previous], edx
  204.         push    sizeof.gif.LogicalScreenDescriptor
  205.         pop     ecx
  206.         test    edx, edx
  207.         jz      @f
  208.         mov     [edx + Image.Next], eax
  209.         xor     ecx, ecx
  210.   @@:
  211.         push    eax
  212.         mov     [eax + Image.Type], Image.bpp8i
  213.  
  214.         add     ecx, sizeof.gif.Image
  215.         invoke  mem.alloc, ecx
  216.         pop     edx
  217.         or      eax, eax
  218.         jz      .error2
  219.         mov     [edx + Image.Extended], eax
  220.         xor     ecx, ecx
  221.         cmp     [img], ecx
  222.         jnz     @f
  223.         mov     esi, [_data]
  224.         add     esi, gif.Header.lsd
  225.         lea     edi, [eax + sizeof.gif.Image]
  226.         mov     cl, sizeof.gif.LogicalScreenDescriptor
  227.         rep     movsb
  228.         mov     [main_img], edx
  229.   @@:
  230.         mov     [img], edx
  231.  
  232.         stdcall ._.process_extensions
  233.  
  234.         cmp     al, gif.Block.Introducer.ImageDescriptor
  235.         jne     .error
  236.         sub     [_length], sizeof.gif.ImageDescriptor
  237.         jc      .error
  238.         movzx   eax, [ebx + gif.ImageDescriptor.Width]
  239.         movzx   ecx, [ebx + gif.ImageDescriptor.Height]
  240.         push    edx
  241.         stdcall img.resize_data, [img], eax, ecx
  242.         pop     edx
  243.         or      eax, eax
  244.         jz      .error
  245.  
  246.         mov     esi, ebx
  247.         mov     edi, [edx + Image.Extended]
  248.         mov     ecx, sizeof.gif.ImageDescriptor
  249.         rep     movsb
  250.  
  251.         mov     edi, [edx + Image.Palette]
  252.         mov     esi, [global_color_table]
  253.         mov     ecx, [global_color_table_size]
  254.         test    [ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
  255.         jz      @f
  256.         lea     esi, [ebx + sizeof.gif.ImageDescriptor]
  257.         mov     cl, [ebx + gif.ImageDescriptor.Packed]
  258.         and     cl, gif.ID.Packed.SizeOfLocalColorTableMask
  259. ; here Shift = 0
  260. ;       shr     cl, gif.ID.Packed.SizeOfLocalColorTableShift
  261.         push    2
  262.         pop     eax
  263.         shl     eax, cl
  264.         mov     ecx, eax
  265.         lea     eax, [eax*3]
  266.         add     ebx, eax
  267.         sub     [_length], eax
  268.         jbe     .error  ; because we load additional byte, check is 'jbe', not 'jc'
  269. @@:
  270.         mov     [cur_color_table_size], ecx
  271.         dec     [cur_color_table_size]
  272. @@:
  273.         lodsd
  274.         dec     esi
  275.         bswap   eax
  276.         mov     al, 0xff        ; opaque
  277.         ror     eax, 8
  278.         stosd
  279.         loop    @b
  280.         add     ebx, sizeof.gif.ImageDescriptor
  281.         stdcall ._.process_image
  282.         push    ebx
  283.         mov     edx, [img]
  284.         push    edx
  285.         stdcall ._.superimpose
  286.         pop     edx
  287.         push    edx
  288.         stdcall ._.dispose
  289.         pop     edx
  290.         mov     edx, [edx + Image.Previous]
  291.         test    edx, edx
  292.         jz      .nofreeprev
  293.         mov     ebx, [edx + Image.Extended]
  294.         cmp     [edx + Image.Delay], 0
  295.         jnz     .nofreeprev
  296.         mov     esi, [prev_palette]
  297.         cmp     esi, [edx + Image.Palette]
  298.         jnz     @f
  299.         mov     ecx, [prev_num_colors]
  300.         stdcall ._.alloc_aux_palette
  301.         test    eax, eax
  302.         jz      .nofreeprev
  303.         mov     [prev_palette], eax
  304.     @@:
  305.         mov     esi, [prev_img_data]
  306.         cmp     esi, [edx + Image.Data]
  307.         jnz     .noprevdata
  308.         push    1
  309.         pop     eax
  310.         cmp     [edx + Image.Type], Image.bpp8i
  311.         jz      @f
  312.         mov     al, 3
  313.     @@:
  314.         cmp     [aux_img_type], eax
  315.         jb      .resetaux
  316.         mov     edi, [aux_img_data]
  317.         imul    eax, [edx + Image.Width]
  318.         imul    eax, [edx + Image.Height]
  319.         xchg    eax, ecx
  320.         rep     movsb
  321.         jmp     .noprevdata
  322.     .resetaux:
  323.         mov     [aux_img_type], eax
  324.         mov     eax, [aux_img_data]
  325.         test    eax, eax
  326.         jz      @f
  327.         invoke  mem.free, eax
  328.     @@:
  329.         xor     eax, eax
  330.         xchg    eax, [edx + Image.Data]
  331.         mov     [aux_img_data], eax
  332.     .noprevdata:
  333.         cmp     edx, [main_img]
  334.         jnz     @f
  335.         mov     eax, [edx + Image.Next]
  336.         mov     [main_img], eax
  337.         mov     esi, [eax + Image.Extended]
  338.         mov     edi, [edx + Image.Extended]
  339.         mov     [edx + Image.Extended], esi
  340.         mov     [eax + Image.Extended], edi
  341.         push    sizeof.gif.Image
  342.         pop     ecx
  343.         rep     movsb
  344.     @@:
  345.         stdcall img.destroy.layer, edx
  346.   .nofreeprev:
  347.         pop     ebx
  348.         test    ebx, ebx
  349.         jz      .ret
  350.         jmp     .next_image
  351.  
  352.   .error2:
  353.         mov     [img], edx
  354.  
  355.   .error:
  356.         mov     eax, [img]
  357.         test    eax, eax
  358.         jz      .ret
  359.         cmp     [main_img], eax
  360.         jnz     @f
  361.         and     [main_img], 0
  362.   @@:
  363.         stdcall img.destroy.layer, eax
  364.   .ret:
  365.         mov     eax, [aux_img_data]
  366.         test    eax, eax
  367.         jz      @f
  368.         invoke  mem.free, eax
  369.   @@:
  370.         mov     eax, [aux_palette]
  371.         test    eax, eax
  372.         jz      @f
  373.         invoke  mem.free, eax
  374.   @@:
  375.         mov     eax, [main_img]
  376.         cmp     [eax + Image.Next], 0
  377.         jz      @f
  378.         or      [eax + Image.Flags], Image.IsAnimated
  379.   @@:
  380.         pop     edi esi ebx
  381.         ret
  382. endp
  383.  
  384. ;;================================================================================================;;
  385. proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
  386. ;;------------------------------------------------------------------------------------------------;;
  387. ;? Encode image into raw data in GIF format                                                       ;;
  388. ;;------------------------------------------------------------------------------------------------;;
  389. ;> _img = pointer to image                                                                        ;;
  390. ;;------------------------------------------------------------------------------------------------;;
  391. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  392. ;< _p_length = encoded data length                                                                ;;
  393. ;;================================================================================================;;
  394.         xor     eax, eax
  395.         ret
  396. endp
  397.  
  398.  
  399. ;;================================================================================================;;
  400. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  401. ;;================================================================================================;;
  402. ;! Below are private procs you should never call directly from your code                          ;;
  403. ;;================================================================================================;;
  404. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  405. ;;================================================================================================;;
  406.  
  407.  
  408. ;;================================================================================================;;
  409. proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
  410. ;;------------------------------------------------------------------------------------------------;;
  411. ;? --- TBD ---                                                                                    ;;
  412. ;;------------------------------------------------------------------------------------------------;;
  413. ;> ebx = raw image data                                                                           ;;
  414. ;> edx = image data                                                                               ;;
  415. ;;------------------------------------------------------------------------------------------------;;
  416. ;< --- TBD ---                                                                                    ;;
  417. ;;================================================================================================;;
  418.         mov     esi, ebx
  419.         xor     eax, eax
  420.         mov     [edx + Image.Delay], eax
  421.  
  422.   .next_block:
  423.         dec     [img.decode.gif._length]
  424.         js      .exit_err
  425.         lodsb   ; load gif.Block.Introducer
  426.         cmp     al, gif.Block.Introducer.Extension
  427.         jne     .exit
  428.  
  429.   .ext_block:
  430.         dec     [img.decode.gif._length]
  431.         js      .exit_err
  432.         lodsb   ; load gif.Extension.Label
  433.         cmp     al, gif.Extension.Label.GraphicsControl
  434.         je      .graphics_control_ext
  435. ;       cmp     al, gif.Extension.Label.PlainText
  436. ;       je      .plain_text_ext
  437. ;       cmp     al, gif.Extension.Label.Comment
  438. ;       je      .comment_ext
  439. ;       cmp     al, gif.Extension.Label.Application
  440. ;       je      .application_ext
  441. ; skip all other extensions
  442.   .skip_ext:
  443.         dec     [img.decode.gif._length]
  444.         js      .exit_err
  445.         lodsb   ; load BlockSize
  446.   .1:
  447.         test    al, al
  448.         jz      .next_block
  449.         sub     [img.decode.gif._length], eax
  450.         jc      .exit_err
  451.         add     esi, eax
  452.         jmp     .skip_ext
  453.  
  454.   .graphics_control_ext:
  455.         dec     [img.decode.gif._length]
  456.         js      .exit_err
  457.         lodsb   ; load BlockSize; must be sizeof.gif.GraphicsControlExtension
  458.         cmp     al, sizeof.gif.GraphicsControlExtension
  459.         jnz     .1
  460.         sub     [img.decode.gif._length], eax
  461.         jc      .exit_err
  462.         push    edi
  463.         movzx   edi, [esi + gif.GraphicsControlExtension.DelayTime]
  464.         mov     [edx + Image.Delay], edi
  465.         mov     edi, [edx + Image.Extended]
  466.         add     edi, gif.Image.gce
  467.         mov     ecx, eax
  468.         rep     movsb
  469.         pop     edi
  470.         jmp     .skip_ext
  471.  
  472.   .exit_err:
  473.         xor     eax, eax
  474.  
  475.   .exit:
  476.         mov     ebx, esi
  477.         ret
  478. endp
  479.  
  480. ;;================================================================================================;;
  481. proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
  482. ;;------------------------------------------------------------------------------------------------;;
  483. ;? --- TBD ---                                                                                    ;;
  484. ;;------------------------------------------------------------------------------------------------;;
  485. ;> ebx = raw image data                                                                           ;;
  486. ;> edx = image data                                                                               ;;
  487. ;;------------------------------------------------------------------------------------------------;;
  488. ;< --- TBD ---                                                                                    ;;
  489. ;;================================================================================================;;
  490. locals
  491.   width      dd ?
  492.   img_start  dd ?
  493.   img_end    dd ?
  494.   row_end    dd ?
  495.   pass       dd ?
  496.   codesize   dd ?
  497.   compsize   dd ?
  498.   workarea   dd ?
  499.   block_ofs  dd ?
  500.   bit_count  dd ?
  501.   CC         dd ?
  502.   EOI        dd ?
  503. endl
  504.  
  505.         invoke  mem.alloc, 16 * 1024
  506.         mov     [workarea], eax
  507.         or      eax, eax
  508.         jz      .error
  509.  
  510.         mov     ecx, [edx + Image.Width]
  511.         mov     [width], ecx
  512.         mov     eax, [edx + Image.Height]
  513.         imul    eax, ecx
  514.         mov     [img_end], eax
  515.         inc     eax
  516.         mov     [row_end], eax
  517.         and     [pass], 0
  518.         and     dword [img.decode.gif.max_color_child], 0
  519.         mov     eax, [edx + Image.Extended]
  520.         test    [eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
  521.         jz      @f
  522.         mov     [row_end], ecx
  523.  
  524.     @@: mov     esi, ebx
  525.         mov     edi, [edx + Image.Data]
  526.  
  527.         sub     dword [img.decode.gif._length_child], 2
  528.         jc      .error
  529.         movzx   ecx, byte[esi]
  530.         inc     esi
  531.         cmp     cl, 12
  532.         jae     .error
  533.         mov     [codesize], ecx
  534.         inc     [codesize]
  535.         xor     eax, eax
  536.         lodsb                           ; eax - block_count
  537.         sub     [img.decode.gif._length_child], eax
  538.         jc      .error
  539.         add     eax, esi
  540.         push    edi
  541.         mov     edi, [workarea]
  542.         mov     [block_ofs], eax
  543.         mov     [bit_count], 8
  544.         mov     eax, 1
  545.         shl     eax, cl
  546.         mov     [CC], eax
  547.         mov     ecx, eax
  548.         inc     eax
  549.         mov     [EOI], eax
  550.         mov     eax, gif.Null shl 16
  551.   .filltable:
  552.         stosd
  553.         inc     eax
  554.         loop    .filltable
  555.         pop     edi
  556.         mov     [img_start], edi
  557.         add     [img_end], edi
  558.         add     [row_end], edi
  559.   .reinit:
  560.         mov     edx, [EOI]
  561.         inc     edx
  562.         push    [codesize]
  563.         pop     [compsize]
  564.         call    .get_symbol
  565.         cmp     eax, [CC]
  566.         je      .reinit
  567.         call    .output
  568.   .cycle:
  569.         movzx   ebx, ax
  570.         call    .get_symbol
  571.         cmp     eax, [EOI]
  572.         je      .end
  573.         cmp     eax, edx
  574.         ja      .error
  575.         je      .notintable
  576.         cmp     eax, [CC]
  577.         je      .reinit
  578.         call    .output
  579.   .add:
  580.         cmp     edx, 0x00001000
  581.         jae     .cycle
  582.         mov     ecx, [workarea]
  583.         mov     [ecx + edx * 4], ebx
  584.         inc     edx
  585.         cmp     edx, 0x1000
  586.         je      .noinc
  587.         bsr     ebx, edx
  588.         cmp     ebx, [compsize]
  589.         jne     .noinc
  590.         inc     [compsize]
  591.   .noinc:
  592.         jmp     .cycle
  593.   .notintable:
  594.         push    eax
  595.         mov     eax, ebx
  596.         call    .output
  597.         push    ebx
  598.         movzx   eax, bx
  599.         call    .output
  600.         pop     ebx eax
  601.         jmp     .add
  602.   .end:
  603.         mov     edi, [img_end]
  604.         xor     eax, eax
  605.  
  606.   .exit:
  607.         cmp     [workarea], 0
  608.         je      @f
  609.         invoke  mem.free, [workarea]
  610.     @@:
  611.         mov     ebx, [block_ofs]
  612.     @@:
  613.         dec     [img.decode.gif._length_child]
  614.         js      @f
  615.         movzx   eax, byte [ebx]
  616.         inc     ebx
  617.         test    eax, eax
  618.         jz      .ret
  619.         sub     [img.decode.gif._length_child], eax
  620.         jc      @f
  621.         add     ebx, eax
  622.         jmp     @b
  623.  
  624.   .error:
  625.         cmp     [workarea], 0
  626.         je      @f
  627.         invoke  mem.free, [workarea]
  628.     @@: xor     ebx, ebx
  629.   .ret:
  630.         ret
  631.  
  632. ;;------------------------------------------------------------------------------------------------;;
  633.  
  634. img.decode.gif._.process_image.get_symbol:
  635.         mov     ecx, [compsize]
  636.         push    ecx
  637.         xor     eax, eax
  638.  
  639.   .shift:
  640.         dec     [bit_count]
  641.         jns     .loop1
  642.         inc     esi
  643.         cmp     esi, [block_ofs]
  644.         jb      .noblock
  645.         push    eax
  646.         xor     eax, eax
  647.         sub     [img.decode.gif._length_child], 1
  648.         jc      .error_eof
  649.         lodsb
  650.         test    eax, eax
  651.         jnz     .nextbl
  652.   .error_eof:
  653.         add     esp, 12
  654.         jmp     img.decode.gif._.process_image.error
  655.  
  656.   .nextbl:
  657.         sub     [img.decode.gif._length_child], eax
  658.         jc      .error_eof
  659.         add     eax, esi
  660.         mov     [block_ofs], eax
  661.         pop     eax
  662.  
  663.   .noblock:
  664.         mov     [bit_count], 7
  665.  
  666.   .loop1:
  667.         ror     byte[esi], 1
  668.         rcr     eax,1
  669.         loop    .shift
  670.         pop     ecx
  671.         rol     eax, cl
  672.  
  673.   .exit:
  674.         xor     ecx, ecx
  675.         retn
  676.  
  677. ;;------------------------------------------------------------------------------------------------;;
  678.  
  679. img.decode.gif._.process_image.output:
  680.         push    esi eax edx
  681.         mov     edx, [workarea]
  682.  
  683.   .next:
  684.         pushw   [edx + eax * 4]
  685.         mov     ax, [edx + eax * 4 + 2]
  686.         inc     ecx
  687.         cmp     ax, gif.Null
  688.         jnz     .next
  689.         shl     ebx, 16
  690.         mov     bx, [esp]
  691.  
  692.   .loop2:
  693.         pop     ax
  694.         cmp     al, byte [img.decode.gif.cur_color_table_size_child]
  695.         jbe     @f      ; guard against incorrect GIFs
  696.         mov     al, 0
  697.     @@: cmp     al, byte [img.decode.gif.max_color_child]
  698.         jbe     @f
  699.         mov     [img.decode.gif.max_color_child], al
  700.     @@: stosb
  701.  
  702.         cmp     edi, [row_end]
  703.         jb      .norowend
  704.         mov     eax, [width]
  705.         push    eax
  706.         sub     edi, eax
  707.         add     eax, eax
  708.         cmp     [pass], 3
  709.         je      @f
  710.         add     eax, eax
  711.         cmp     [pass], 2
  712.         je      @f
  713.         add     eax, eax
  714.     @@: add     edi, eax
  715.         pop     eax
  716.         cmp     edi, [img_end]
  717.         jb      .nextrow
  718.         mov     edi, [img_start]
  719.         inc     [pass]
  720.         cmp     [pass], 4
  721.         je      .done
  722.         add     edi, eax
  723.         cmp     [pass], 3
  724.         je      @f
  725.         add     edi, eax
  726.         cmp     [pass], 2
  727.         je      @f
  728.         add     edi, eax
  729.         add     edi, eax
  730.     @@:
  731.  
  732.   .nextrow:
  733.         add     eax, edi
  734.         mov     [row_end], eax
  735.         xor     eax, eax
  736.  
  737.   .norowend:
  738.         cmp     edi, [img_end]
  739.         jz      .done
  740.         loop    .loop2
  741.         pop     edx eax esi
  742.         retn
  743.  
  744.   .done:
  745.         lea     esp, [esp+(ecx-1)*2]
  746.         pop     edx eax esi eax
  747.         jmp     img.decode.gif._.process_image.exit
  748.  
  749. endp
  750.  
  751. ;;================================================================================================;;
  752. proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
  753. ;;------------------------------------------------------------------------------------------------;;
  754. ;? Determines whether GIF image occupies the whole logical screen                                 ;;
  755. ;;------------------------------------------------------------------------------------------------;;
  756. ;> eax = extended image data                                                                      ;;
  757. ;> ebx = main image                                                                               ;;
  758. ;;------------------------------------------------------------------------------------------------;;
  759. ;< ZF set <=> image area equals logical screen                                                    ;;
  760. ;;================================================================================================;;
  761.         mov     ebx, [ebx + Image.Extended]
  762.         cmp     [eax + gif.Image.info.Left], 0
  763.         jnz     @f
  764.         cmp     [eax + gif.Image.info.Top], 0
  765.         jnz     @f
  766.         mov     cx, [eax + gif.Image.info.Width]
  767.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  768.         jnz     @f
  769.         mov     cx, [eax + gif.Image.info.Height]
  770.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  771. @@:     retn
  772. endp
  773.  
  774. main_img equ img.decode.gif.main_img
  775. transparent_color equ img.decode.gif.transparent_color
  776. background_color equ img.decode.gif.background_color
  777. prev_num_colors equ img.decode.gif.prev_num_colors
  778. prev_palette equ img.decode.gif.prev_palette
  779. max_color equ img.decode.gif.max_color
  780. prev_img_data equ img.decode.gif.prev_img_data
  781. _data equ img.decode.gif._data
  782. aux_img_data equ img.decode.gif.aux_img_data
  783. aux_img_type equ img.decode.gif.aux_img_type
  784. aux_palette equ img.decode.gif.aux_palette
  785.  
  786. ;;================================================================================================;;
  787. proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
  788. ;;------------------------------------------------------------------------------------------------;;
  789. ;? --- TBD ---                                                                                    ;;
  790. ;;------------------------------------------------------------------------------------------------;;
  791. ;> edx = image data                                                                               ;;
  792. ;;------------------------------------------------------------------------------------------------;;
  793. ;< --- TBD ---                                                                                    ;;
  794. ;;================================================================================================;;
  795.         mov     ebx, [main_img]
  796.         mov     eax, [edx + Image.Extended]
  797.         or      [transparent_color], -1         ; no transparent color
  798.         test    byte [eax + gif.Image.gce.Packed], 1
  799.         jz      @f
  800.         movzx   ecx, byte [eax + gif.Image.gce.ColorIndex]
  801.         mov     [transparent_color], ecx
  802.         cmp     edx, ebx
  803.         jnz     .has_transparency
  804.         shl     ecx, 2
  805.         add     ecx, [edx + Image.Palette]
  806.         push    eax
  807.         mov     eax, [img.decode.gif.options_bgr]
  808.         mov     dword [background_color], eax
  809.         mov     dword [ecx], eax
  810.         pop     eax
  811. @@:
  812.         call    img.decode.gif._.is_logical_screen
  813.         jnz     .has_transparency
  814. ; image is not transparent, so keep it as is
  815.         retn
  816.  
  817. .has_transparency:
  818. ; image has transparent areas, we must superimpose it on the previous
  819.         mov     ecx, [prev_num_colors]
  820.         cmp     ecx, 0x100
  821.         ja      .superimpose_on_rgb
  822. ; create common palette
  823.         sub     esp, 3FCh
  824.         push    eax
  825.         mov     edi, esp
  826.         push    ecx
  827.         mov     esi, [prev_palette]
  828.         rep     movsd
  829.         pop     ecx
  830.         mov     esi, [edx + Image.Palette]
  831.         xor     ebx, ebx
  832.         mov     edi, esp
  833.         sub     esp, 100h
  834. .create_palette_loop:
  835.         push    ecx
  836.         lodsd
  837.         cmp     ebx, [transparent_color]
  838.         jz      .nochange
  839.         cmp     ebx, ecx
  840.         jae     @f
  841.         cmp     eax, [edi+ebx*4]
  842.         jz      .nochange
  843. @@:
  844.         push    edi
  845.         repnz   scasd
  846.         pop     edi
  847.         jnz     .increase_palette
  848.         sub     ecx, [esp]
  849.         not     ecx     ; cl = index of new color in current palette
  850.         jmp     .palette_common
  851. .increase_palette:
  852.         mov     ecx, [esp]
  853.         test    ch, ch
  854.         jnz     .output_to_rgb
  855.         inc     dword [esp]
  856.         mov     [edi+ecx*4], eax
  857.         jmp     .palette_common
  858. .nochange:
  859.         mov     ecx, ebx
  860. .palette_common:
  861.         mov     [ebx+esp+4], cl
  862.         pop     ecx
  863.         inc     ebx
  864.         cmp     ebx, [max_color]
  865.         jbe     .create_palette_loop
  866.         mov     [max_color], ecx
  867. ; if image occupies only part of logical screen, allocate memory for full logical screen
  868.         mov     ebx, [main_img]
  869.         mov     eax, [edx + Image.Extended]
  870.         mov     esi, [edx + Image.Data]
  871.         call    img.decode.gif._.is_logical_screen
  872.         jz      @f
  873.         and     [edx + Image.Data], 0
  874.         push    edx
  875.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  876.         push    eax
  877.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  878.         stdcall img.resize_data, edx, eax
  879.         pop     edx
  880.         test    eax, eax
  881.         jz      .palette_nomem
  882. @@:
  883. ; copy final palette to Image.Palette
  884.         push    esi esi
  885.         mov     esi, edi
  886.         mov     edi, [edx + Image.Palette]
  887.         mov     ecx, [max_color]
  888.         dec     [max_color]
  889.         rep     movsd
  890.         mov     esi, [prev_img_data]
  891.         mov     edi, [edx + Image.Data]
  892. ; do superimpose, [esp] -> source data, esi -> prev image data
  893. ;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
  894. ;   used palette and final palette, edi -> destination data
  895.         mov     ebx, [edx + Image.Extended]
  896. ; first Top rows are copied from [prev_img_data] or filled with bgr
  897.         movzx   ecx, [ebx + gif.Image.info.Top]
  898.         cmp     ecx, [edx + Image.Height]
  899.         jb      @f
  900.         mov     ecx, [edx + Image.Height]
  901. @@:
  902.         push    ecx
  903.         imul    ecx, [edx + Image.Width]
  904.         call    .rep_movsb_or_stosb
  905.         pop     ecx
  906. ; convert rows
  907.         sub     ecx, [edx + Image.Height]
  908.         neg     ecx
  909.         push    ecx
  910.         cmp     cx, [ebx + gif.Image.info.Height]
  911.         jbe     @f
  912.         mov     cx, [ebx + gif.Image.info.Height]
  913. @@:
  914.         jecxz   .norows
  915. .convert_rows:
  916.         push    ecx
  917.         movzx   ecx, [ebx + gif.Image.info.Left]
  918.         cmp     ecx, [edx + Image.Width]
  919.         jb      @f
  920.         mov     ecx, [edx + Image.Width]
  921. @@:
  922.         push    ecx
  923.         call    .rep_movsb_or_stosb
  924.         pop     ecx
  925.         sub     ecx, [edx + Image.Width]
  926.         neg     ecx
  927.         push    ecx edx
  928.         mov     edx, [esp+16]   ; source data
  929.         cmp     cx, [ebx + gif.Image.info.Width]
  930.         jbe     @f
  931.         mov     cx, [ebx + gif.Image.info.Width]
  932. @@:
  933.         jecxz   .norowsi
  934. .rowsloop:
  935.         movzx   eax, byte [edx]
  936.         inc     edx
  937.         cmp     eax, [transparent_color]
  938.         jz      .rows_transparent
  939.         mov     al, [eax+esp+24]
  940.         stosb
  941.         call    .lodsb
  942.         jmp     @f
  943. .rows_transparent:
  944.         call    .lodsb
  945.         stosb
  946. @@:
  947.         loop    .rowsloop
  948. .norowsi:
  949.         pop     edx ecx
  950.         sub     cx, [ebx + gif.Image.info.Width]
  951.         jbe     @f
  952.         call    .rep_movsb_or_stosb
  953. @@:
  954.         movzx   eax, [ebx + gif.Image.info.Width]
  955.         add     [esp+8], eax
  956.         pop     ecx
  957.         loop    .convert_rows
  958. .norows:
  959.         pop     ecx
  960.         sub     cx, [ebx + gif.Image.info.Height]
  961.         jbe     @f
  962.         imul    ecx, [edx + Image.Width]
  963.         call    .rep_movsb_or_stosb
  964. @@:
  965. ; free old image data if we have allocated new copy
  966.         pop     esi esi
  967.         cmp     esi, [edx + Image.Data]
  968.         jz      @f
  969.         invoke  mem.free, esi
  970. @@:
  971. ; cleanup stack and return
  972.         add     esp, 500h
  973.         retn
  974. .palette_nomem:
  975.         mov     [edx + Image.Data], esi
  976.         jmp     @b
  977.  
  978. .output_to_rgb:
  979.         pop     ecx
  980.         add     esp, 500h
  981. ; compose two palette-based images to one RGB image
  982.         xor     esi, esi
  983.         xchg    esi, [edx + Image.Data]
  984.         push    esi
  985.         mov     ebx, [_data]
  986.         push    [edx + Image.Palette]
  987.         mov     byte [edx + Image.Type], Image.bpp24
  988.         push    edx
  989.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  990.         push    eax
  991.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  992.         stdcall img.resize_data, edx, eax
  993.         pop     edx
  994.         test    eax, eax
  995.         jz      .convrgb_nomem
  996.         push    esi
  997.         mov     edi, [edx + Image.Data]
  998.         mov     esi, [prev_img_data]
  999.         mov     ebx, [edx + Image.Extended]
  1000. ; first Top rows are copied from [prev_img_data] or filled with bgr
  1001.         movzx   ecx, [ebx + gif.Image.info.Top]
  1002.         cmp     ecx, [edx + Image.Height]
  1003.         jb      @f
  1004.         mov     ecx, [edx + Image.Height]
  1005. @@:
  1006.         push    ecx
  1007.         imul    ecx, [edx + Image.Width]
  1008.         call    .convrgb_prev
  1009.         pop     ecx
  1010. ; convert rows
  1011.         sub     ecx, [edx + Image.Height]
  1012.         neg     ecx
  1013.         push    ecx
  1014.         cmp     cx, [ebx + gif.Image.info.Height]
  1015.         jbe     @f
  1016.         mov     cx, [ebx + gif.Image.info.Height]
  1017. @@:
  1018.         jecxz   .convrgb_norows
  1019. .convrgb_convert_rows:
  1020.         push    ecx
  1021.         movzx   ecx, [ebx + gif.Image.info.Left]
  1022.         cmp     ecx, [edx + Image.Width]
  1023.         jb      @f
  1024.         mov     ecx, [edx + Image.Width]
  1025. @@:
  1026.         push    ecx
  1027.         call    .convrgb_prev
  1028.         pop     ecx
  1029.         sub     ecx, [edx + Image.Width]
  1030.         neg     ecx
  1031.         push    ecx edx
  1032.         mov     edx, [esp+16]   ; source data
  1033.         cmp     cx, [ebx + gif.Image.info.Width]
  1034.         jbe     @f
  1035.         mov     cx, [ebx + gif.Image.info.Width]
  1036. @@:
  1037.         jecxz   .convrgb_norowsi
  1038. .convrgb_rowsloop:
  1039.         movzx   eax, byte [edx]
  1040.         inc     edx
  1041.         cmp     eax, [transparent_color]
  1042.         jz      .convrgb_rows_transparent
  1043.         shl     eax, 2
  1044.         add     eax, [esp+20]   ; source palette
  1045.         mov     eax, [eax]
  1046.         stosw
  1047.         shr     eax, 16
  1048.         stosb
  1049.         call    .convrgb_lodsb
  1050.         jmp     @f
  1051. .convrgb_rows_transparent:
  1052.         call    .convrgb_lodsb
  1053.         stosw
  1054.         shr     eax, 16
  1055.         stosb
  1056. @@:
  1057.         loop    .convrgb_rowsloop
  1058. .convrgb_norowsi:
  1059.         pop     edx ecx
  1060.         sub     cx, [ebx + gif.Image.info.Width]
  1061.         jbe     @f
  1062.         call    .convrgb_prev
  1063. @@:
  1064.         movzx   eax, [ebx + gif.Image.info.Width]
  1065.         add     [esp+8], eax
  1066.         pop     ecx
  1067.         loop    .convrgb_convert_rows
  1068. .convrgb_norows:
  1069.         pop     ecx
  1070.         sub     cx, [ebx + gif.Image.info.Height]
  1071.         jbe     @f
  1072.         imul    ecx, [edx + Image.Width]
  1073.         call    .convrgb_prev
  1074. @@:
  1075. ; free old image data
  1076.         pop     esi esi ;esi
  1077.         invoke  mem.free;, esi
  1078.         retn
  1079. .convrgb_nomem:
  1080.         pop     esi esi
  1081.         retn
  1082.  
  1083. .superimpose_on_rgb:
  1084. ; previous image is RGB, new image has transparent areas
  1085.         xor     esi, esi
  1086.         xchg    esi, [edx + Image.Data]
  1087.         push    esi
  1088.         mov     ebx, [_data]
  1089.         push    [edx + Image.Palette]
  1090.         mov     byte [edx + Image.Type], Image.bpp24
  1091.         push    edx
  1092.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1093.         push    eax
  1094.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1095.         stdcall img.resize_data, edx, eax
  1096.         pop     edx
  1097.         test    eax, eax
  1098.         jz      .rgb_nomem
  1099.         push    esi
  1100.         mov     edi, [edx + Image.Data]
  1101.         mov     esi, [prev_img_data]
  1102.         mov     ebx, [edx + Image.Extended]
  1103. ; first Top rows are copied from [prev_img_data] or filled with bgr
  1104.         movzx   ecx, [ebx + gif.Image.info.Top]
  1105.         cmp     ecx, [edx + Image.Height]
  1106.         jb      @f
  1107.         mov     ecx, [edx + Image.Height]
  1108. @@:
  1109.         push    ecx
  1110.         lea     ecx, [ecx*3]
  1111.         imul    ecx, [edx + Image.Width]
  1112.         rep     movsb
  1113.         pop     ecx
  1114. ; convert rows
  1115.         sub     ecx, [edx + Image.Height]
  1116.         neg     ecx
  1117.         push    ecx
  1118.         cmp     cx, [ebx + gif.Image.info.Height]
  1119.         jbe     @f
  1120.         mov     cx, [ebx + gif.Image.info.Height]
  1121. @@:
  1122.         jecxz   .rgb_norows
  1123. .rgb_convert_rows:
  1124.         push    ecx
  1125.         movzx   ecx, [ebx + gif.Image.info.Left]
  1126.         cmp     ecx, [edx + Image.Width]
  1127.         jb      @f
  1128.         mov     ecx, [edx + Image.Width]
  1129. @@:
  1130.         push    ecx
  1131.         lea     ecx, [ecx*3]
  1132.         rep     movsb
  1133.         pop     ecx
  1134.         sub     ecx, [edx + Image.Width]
  1135.         neg     ecx
  1136.         push    ecx edx
  1137.         mov     edx, [esp+16]   ; source data
  1138.         cmp     cx, [ebx + gif.Image.info.Width]
  1139.         jbe     @f
  1140.         mov     cx, [ebx + gif.Image.info.Width]
  1141. @@:
  1142.         jecxz   .rgb_norowsi
  1143. .rgb_rowsloop:
  1144.         movzx   eax, byte [edx]
  1145.         inc     edx
  1146.         cmp     eax, [transparent_color]
  1147.         jz      .rgb_rows_transparent
  1148.         shl     eax, 2
  1149.         add     eax, [esp+20]   ; source palette
  1150.         mov     eax, [eax]
  1151.         stosw
  1152.         shr     eax, 16
  1153.         stosb
  1154.         add     esi, 3
  1155.         jmp     @f
  1156. .rgb_rows_transparent:
  1157.         movsb
  1158.         movsb
  1159.         movsb
  1160. @@:
  1161.         loop    .rgb_rowsloop
  1162. .rgb_norowsi:
  1163.         pop     edx ecx
  1164.         sub     cx, [ebx + gif.Image.info.Width]
  1165.         jbe     @f
  1166.         lea     ecx, [ecx*3]
  1167.         rep     movsb
  1168. @@:
  1169.         movzx   eax, [ebx + gif.Image.info.Width]
  1170.         add     [esp+8], eax
  1171.         pop     ecx
  1172.         loop    .rgb_convert_rows
  1173. .rgb_norows:
  1174.         pop     ecx
  1175.         sub     cx, [ebx + gif.Image.info.Height]
  1176.         jbe     @f
  1177.         imul    ecx, [edx + Image.Width]
  1178.         lea     ecx, [ecx*3]
  1179.         rep     movsb
  1180. @@:
  1181. ; free old image data
  1182.         pop     esi esi ;esi
  1183.         invoke  mem.free;, esi
  1184.         retn
  1185. .rgb_nomem:
  1186.         pop     esi esi
  1187.         retn
  1188.  
  1189. .lodsb:
  1190.         xor     eax, eax
  1191.         test    esi, esi
  1192.         jz      @f
  1193.         lodsb
  1194. @@:     retn
  1195.  
  1196. .rep_movsb_or_stosb:
  1197.         test    esi, esi
  1198.         jz      .rmos1
  1199.         rep     movsb
  1200.         jmp     .rmos2
  1201. .rmos1: xor     eax, eax        ; background index in final palette is 0 in bgr mode
  1202.         rep     stosb
  1203. .rmos2: retn
  1204.  
  1205. .convrgb_prev:
  1206.         jecxz   .convrgb_noprev
  1207.         test    esi, esi
  1208.         jz      .convrgb_prev_bgr
  1209. @@:
  1210.         xor     eax, eax
  1211.         lodsb
  1212.         shl     eax, 2
  1213.         add     eax, [prev_palette]
  1214.         mov     eax, [eax]
  1215.         stosw
  1216.         shr     eax, 16
  1217.         stosb
  1218.         loop    @b
  1219.         retn
  1220. .convrgb_prev_bgr:
  1221. @@:
  1222.         mov     eax, [background_color]
  1223.         stosw
  1224.         shr     eax, 16
  1225.         stosb
  1226.         loop    @b
  1227. .convrgb_noprev:
  1228.         retn
  1229. .convrgb_lodsb:
  1230.         xor     eax, eax
  1231.         test    esi, esi
  1232.         jz      @f
  1233.         lodsb
  1234.         shl     eax, 2
  1235.         add     eax, [prev_palette]
  1236.         mov     eax, [eax]
  1237.         retn
  1238. @@:     mov     eax, [background_color]
  1239.         retn
  1240.  
  1241. endp
  1242.  
  1243. ;;================================================================================================;;
  1244. proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
  1245. ;;------------------------------------------------------------------------------------------------;;
  1246. ;? --- TBD ---                                                                                    ;;
  1247. ;;------------------------------------------------------------------------------------------------;;
  1248. ;> edx = image data                                                                               ;;
  1249. ;;------------------------------------------------------------------------------------------------;;
  1250. ;< --- TBD ---                                                                                    ;;
  1251. ;;================================================================================================;;
  1252.         mov     ebx, [edx + Image.Extended]
  1253.         mov     al, [ebx + gif.Image.gce.Packed]
  1254.         shr     al, 2
  1255.         and     al, 7
  1256.         cmp     al, 2
  1257.         jz      .background
  1258.         cmp     al, 3
  1259.         jz      .previous
  1260. ; don't dispose - set prev_img and related vars to current image
  1261.         mov     eax, [edx + Image.Data]
  1262.         mov     [prev_img_data], eax
  1263.         cmp     [edx + Image.Type], Image.bpp8i
  1264.         jnz     @f
  1265.         mov     eax, [max_color]
  1266.         inc     eax
  1267.         mov     [prev_num_colors], eax
  1268.         mov     eax, [edx + Image.Palette]
  1269.         mov     [prev_palette], eax
  1270.         retn
  1271. @@:
  1272.         or      [prev_num_colors], -1
  1273.         and     [prev_palette], 0
  1274. .previous:
  1275.         retn
  1276. .background:
  1277.         cmp     [prev_img_data], 0
  1278.         jz      .bgr_full
  1279.         mov     ebx, [main_img]
  1280.         mov     eax, [edx + Image.Extended]
  1281.         call    img.decode.gif._.is_logical_screen
  1282.         jnz     @f
  1283. .bgr_full:
  1284.         xor     eax, eax
  1285.         mov     [prev_img_data], eax
  1286.         inc     eax
  1287.         mov     [prev_num_colors], eax
  1288.         lea     eax, [background_color]
  1289.         mov     [prev_palette], eax
  1290.         retn
  1291. @@:
  1292.         cmp     [prev_num_colors], 0x100
  1293.         ja      .rgb
  1294.         mov     eax, [background_color]
  1295.         mov     edi, [prev_palette]
  1296.         mov     ecx, [prev_num_colors]
  1297.         repnz   scasd
  1298.         jz      .palette_ok
  1299.         cmp     [prev_num_colors], 0x100
  1300.         jz      .convert_rgb
  1301.         push    1
  1302.         pop     eax
  1303.         stdcall img.decode.gif._.alloc_aux_img
  1304.         test    eax, eax
  1305.         jz      .previous
  1306.         mov     ecx, [prev_num_colors]
  1307.         mov     esi, [prev_palette]
  1308.         call    img.decode.gif._.alloc_aux_palette
  1309.         test    eax, eax
  1310.         jz      .previous
  1311.         mov     [prev_palette], eax
  1312.         mov     eax, [background_color]
  1313.         stosd
  1314.         mov     eax, [prev_num_colors]  ; eax = index of background color
  1315.         inc     [prev_num_colors]
  1316.         jmp     .bpp8_common
  1317. .palette_ok:
  1318.         push    1
  1319.         pop     eax
  1320.         stdcall img.decode.gif._.alloc_aux_img
  1321.         test    eax, eax
  1322.         jz      .previous
  1323.         sub     edi, [prev_palette]
  1324.         shr     edi, 2
  1325.         lea     eax, [edi-1]    ; eax = index of background color
  1326. .bpp8_common:
  1327.         push    eax
  1328.         mov     ebx, [_data]
  1329.         mov     esi, [prev_img_data]
  1330.         mov     edi, [aux_img_data]
  1331.         mov     [prev_img_data], edi
  1332.         cmp     esi, edi
  1333.         jz      @f
  1334.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1335.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1336.         imul    ecx, eax
  1337.         push    edi
  1338.         rep     movsb
  1339.         pop     edi
  1340. @@:
  1341.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1342.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1343.         mov     edx, [edx + Image.Extended]
  1344.         movzx   ecx, [edx + gif.Image.info.Top]
  1345.         sub     esi, ecx
  1346.         jbe     .bpp8_ret
  1347.         imul    ecx, eax
  1348.         add     edi, ecx
  1349.         cmp     si, [edx + gif.Image.info.Height]
  1350.         jb      @f
  1351.         mov     si, [edx + gif.Image.info.Height]
  1352. @@:
  1353.         movzx   ecx, [edx + gif.Image.info.Left]
  1354.         sub     eax, ecx
  1355.         jbe     .bpp8_ret
  1356.         add     edi, ecx
  1357.         cmp     ax, [edx + gif.Image.info.Width]
  1358.         jb      @f
  1359.         mov     ax, [edx + gif.Image.info.Width]
  1360. @@:
  1361.         xchg    eax, ecx
  1362.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1363.         sub     edx, ecx
  1364.         pop     eax
  1365. @@:
  1366.         push    ecx
  1367.         rep     stosb
  1368.         pop     ecx
  1369.         add     edi, edx
  1370.         dec     esi
  1371.         jnz     @b
  1372.         push    eax
  1373. .bpp8_ret:
  1374.         pop     eax
  1375.         retn
  1376. .convert_rgb:
  1377.         push    3
  1378.         pop     eax
  1379.         stdcall img.decode.gif._.alloc_aux_img
  1380.         test    eax, eax
  1381.         jz      .previous
  1382.         or      [prev_num_colors], -1
  1383.         mov     ebx, [_data]
  1384.         mov     esi, [prev_img_data]
  1385.         mov     edi, [aux_img_data]
  1386.         mov     [prev_img_data], edi
  1387.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1388.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1389.         imul    ecx, eax
  1390.         push    edx
  1391.         xor     edx, edx
  1392.         xchg    edx, [prev_palette]
  1393.         add     edi, ecx
  1394.         add     esi, ecx
  1395.         add     edi, ecx
  1396.         add     edi, ecx
  1397. @@:
  1398.         dec     esi
  1399.         movzx   eax, byte [esi]
  1400.         mov     eax, [eax*4+edx]
  1401.         sub     edi, 3
  1402.         mov     [edi], ax
  1403.         shr     eax, 16
  1404.         mov     [edi+2], al
  1405.         loop    @b
  1406.         pop     edx
  1407.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1408.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1409.         mov     edx, [edx + Image.Extended]
  1410.         movzx   ecx, [edx + gif.Image.info.Top]
  1411.         sub     esi, ecx
  1412.         jbe     .convert_rgb_ret
  1413.         imul    ecx, eax
  1414.         lea     ecx, [ecx*3]
  1415.         add     edi, ecx
  1416.         cmp     si, [edx + gif.Image.info.Height]
  1417.         jb      @f
  1418.         mov     si, [edx + gif.Image.info.Height]
  1419. @@:
  1420.         movzx   ecx, [edx + gif.Image.info.Left]
  1421.         sub     eax, ecx
  1422.         jbe     .convert_rgb_ret
  1423.         lea     ecx, [ecx*3]
  1424.         add     edi, ecx
  1425.         cmp     ax, [edx + gif.Image.info.Width]
  1426.         jb      @f
  1427.         mov     ax, [edx + gif.Image.info.Width]
  1428. @@:
  1429.         xchg    eax, ecx
  1430.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1431.         sub     edx, ecx
  1432.         mov     eax, [background_color]
  1433.         lea     edx, [edx*3]
  1434. .convert_rgb_loop:
  1435.         push    ecx
  1436. @@:
  1437.         stosw
  1438.         shr     eax, 16
  1439.         stosb
  1440.         loop    @b
  1441.         pop     ecx
  1442.         add     edi, edx
  1443.         dec     esi
  1444.         jnz     .convert_rgb_loop
  1445. .convert_rgb_ret:
  1446.         retn
  1447. .rgb:
  1448.         push    3
  1449.         pop     eax
  1450.         stdcall img.decode.gif._.alloc_aux_img
  1451.         test    eax, eax
  1452.         jz      .previous
  1453.         or      [prev_num_colors], -1
  1454.         and     [prev_palette], 0
  1455.         mov     ebx, [_data]
  1456.         mov     esi, [prev_img_data]
  1457.         mov     edi, [aux_img_data]
  1458.         mov     [prev_img_data], edi
  1459.         cmp     esi, edi
  1460.         jz      @f
  1461.         movzx   ecx, [ebx + gif.Header.lsd.ScreenHeight]
  1462.         push    ecx
  1463.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1464.         imul    ecx, eax
  1465.         lea     ecx, [ecx*3]
  1466.         push    edi
  1467.         rep     movsb
  1468.         pop     edi
  1469.         pop     esi
  1470.         mov     edx, [edx + Image.Extended]
  1471.         movzx   ecx, [edx + gif.Image.info.Top]
  1472.         sub     esi, ecx
  1473.         jbe     .rgb_ret
  1474.         imul    ecx, eax
  1475.         lea     ecx, [ecx*3]
  1476.         add     edi, ecx
  1477.         cmp     si, [edx + gif.Image.info.Height]
  1478.         jb      @f
  1479.         mov     si, [edx + gif.Image.info.Height]
  1480. @@:
  1481.         movzx   ecx, [edx + gif.Image.info.Left]
  1482.         sub     eax, ecx
  1483.         jbe     .rgb_ret
  1484.         lea     ecx, [ecx*3]
  1485.         add     edi, ecx
  1486.         cmp     ax, [edx + gif.Image.info.Width]
  1487.         jb      @f
  1488.         mov     ax, [edx + gif.Image.info.Width]
  1489. @@:
  1490.         xchg    eax, ecx
  1491.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1492.         sub     edx, ecx
  1493.         mov     eax, [background_color]
  1494.         lea     edx, [edx*3]
  1495. .rgb_loop:
  1496.         push    ecx
  1497. @@:
  1498.         stosw
  1499.         shr     eax, 16
  1500.         stosb
  1501.         loop    @b
  1502.         pop     ecx
  1503.         add     edi, edx
  1504.         dec     esi
  1505.         jnz     .rgb_loop
  1506. .rgb_ret:
  1507.         retn
  1508.  
  1509. endp
  1510.  
  1511. ;;================================================================================================;;
  1512. proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
  1513. ;;------------------------------------------------------------------------------------------------;;
  1514. ;? Allocate auxiliary memory for previous image                                                   ;;
  1515. ;;------------------------------------------------------------------------------------------------;;
  1516. ;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
  1517. ;;------------------------------------------------------------------------------------------------;;
  1518. ;< eax = [aux_img_data]                                                                           ;;
  1519. ;;================================================================================================;;
  1520.         cmp     [aux_img_type], eax
  1521.         jae     @f
  1522.         push    edx eax
  1523.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  1524.         mul     ecx
  1525.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  1526.         mul     ecx
  1527.         invoke  mem.realloc, [aux_img_data], eax
  1528.         pop     ecx edx
  1529.         test    eax, eax
  1530.         jz      @f
  1531.         mov     [aux_img_type], ecx
  1532.         mov     [aux_img_data], eax
  1533. @@:     retn
  1534.  
  1535. endp
  1536.  
  1537. ;;================================================================================================;;
  1538. proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
  1539. ;;------------------------------------------------------------------------------------------------;;
  1540. ;? Allocate and fill aux_palette                                                                  ;;
  1541. ;;------------------------------------------------------------------------------------------------;;
  1542. ;> esi -> palette, ecx = palette size                                                             ;;
  1543. ;;------------------------------------------------------------------------------------------------;;
  1544. ;< [aux_palette] set                                                                              ;;
  1545. ;;================================================================================================;;
  1546.         mov     eax, [aux_palette]
  1547.         test    eax, eax
  1548.         jnz     @f
  1549.         push    edx ecx
  1550.         invoke  mem.alloc, 0x400
  1551.         pop     ecx edx
  1552.         test    eax, eax
  1553.         jz      .ret
  1554.         mov     [aux_palette], eax
  1555. @@:
  1556.         mov     edi, eax
  1557.         rep     movsd
  1558. .ret:
  1559.         retn
  1560.  
  1561. endp
  1562.  
  1563. restore main_img
  1564. restore transparent_color
  1565. restore background_color
  1566. restore prev_num_colors
  1567. restore prev_palette
  1568. restore max_color
  1569. restore prev_img_data
  1570. restore _data
  1571. restore aux_img_data
  1572. restore aux_img_type
  1573. restore aux_palette
  1574.  
  1575. ;;================================================================================================;;
  1576. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1577. ;;================================================================================================;;
  1578. ;! Below is private data you should never use directly from your code                             ;;
  1579. ;;================================================================================================;;
  1580. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1581. ;;================================================================================================;;
  1582.  
  1583.  
  1584. ;
  1585.