Subversion Repositories Kolibri OS

Rev

Rev 1121 | Rev 8341 | Go to most recent revision | 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.         shr     eax, 8
  277.         stosd
  278.         loop    @b
  279.         add     ebx, sizeof.gif.ImageDescriptor
  280.         stdcall ._.process_image
  281.         push    ebx
  282.         mov     edx, [img]
  283.         push    edx
  284.         stdcall ._.superimpose
  285.         pop     edx
  286.         push    edx
  287.         stdcall ._.dispose
  288.         pop     edx
  289.         mov     edx, [edx + Image.Previous]
  290.         test    edx, edx
  291.         jz      .nofreeprev
  292.         mov     ebx, [edx + Image.Extended]
  293.         cmp     [edx + Image.Delay], 0
  294.         jnz     .nofreeprev
  295.         mov     esi, [prev_palette]
  296.         cmp     esi, [edx + Image.Palette]
  297.         jnz     @f
  298.         mov     ecx, [prev_num_colors]
  299.         stdcall ._.alloc_aux_palette
  300.         test    eax, eax
  301.         jz      .nofreeprev
  302.         mov     [prev_palette], eax
  303.     @@:
  304.         mov     esi, [prev_img_data]
  305.         cmp     esi, [edx + Image.Data]
  306.         jnz     .noprevdata
  307.         push    1
  308.         pop     eax
  309.         cmp     [edx + Image.Type], Image.bpp8i
  310.         jz      @f
  311.         mov     al, 3
  312.     @@:
  313.         cmp     [aux_img_type], eax
  314.         jb      .resetaux
  315.         mov     edi, [aux_img_data]
  316.         imul    eax, [edx + Image.Width]
  317.         imul    eax, [edx + Image.Height]
  318.         xchg    eax, ecx
  319.         rep     movsb
  320.         jmp     .noprevdata
  321.     .resetaux:
  322.         mov     [aux_img_type], eax
  323.         mov     eax, [aux_img_data]
  324.         test    eax, eax
  325.         jz      @f
  326.         invoke  mem.free, eax
  327.     @@:
  328.         xor     eax, eax
  329.         xchg    eax, [edx + Image.Data]
  330.         mov     [aux_img_data], eax
  331.     .noprevdata:
  332.         cmp     edx, [main_img]
  333.         jnz     @f
  334.         mov     eax, [edx + Image.Next]
  335.         mov     [main_img], eax
  336.         mov     esi, [eax + Image.Extended]
  337.         mov     edi, [edx + Image.Extended]
  338.         mov     [edx + Image.Extended], esi
  339.         mov     [eax + Image.Extended], edi
  340.         push    sizeof.gif.Image
  341.         pop     ecx
  342.         rep     movsb
  343.     @@:
  344.         stdcall img.destroy.layer, edx
  345.   .nofreeprev:
  346.         pop     ebx
  347.         test    ebx, ebx
  348.         jz      .ret
  349.         jmp     .next_image
  350.  
  351.   .error2:
  352.         mov     [img], edx
  353.  
  354.   .error:
  355.         mov     eax, [img]
  356.         test    eax, eax
  357.         jz      .ret
  358.         cmp     [main_img], eax
  359.         jnz     @f
  360.         and     [main_img], 0
  361.   @@:
  362.         stdcall img.destroy.layer, eax
  363.   .ret:
  364.         mov     eax, [aux_img_data]
  365.         test    eax, eax
  366.         jz      @f
  367.         invoke  mem.free, eax
  368.   @@:
  369.         mov     eax, [aux_palette]
  370.         test    eax, eax
  371.         jz      @f
  372.         invoke  mem.free, eax
  373.   @@:
  374.         mov     eax, [main_img]
  375.         cmp     [eax + Image.Next], 0
  376.         jz      @f
  377.         or      [eax + Image.Flags], Image.IsAnimated
  378.   @@:
  379.         pop     edi esi ebx
  380.         ret
  381. endp
  382.  
  383. ;;================================================================================================;;
  384. proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
  385. ;;------------------------------------------------------------------------------------------------;;
  386. ;? Encode image into raw data in GIF format                                                       ;;
  387. ;;------------------------------------------------------------------------------------------------;;
  388. ;> _img = pointer to image                                                                        ;;
  389. ;;------------------------------------------------------------------------------------------------;;
  390. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  391. ;< _p_length = encoded data length                                                                ;;
  392. ;;================================================================================================;;
  393.         xor     eax, eax
  394.         ret
  395. endp
  396.  
  397.  
  398. ;;================================================================================================;;
  399. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  400. ;;================================================================================================;;
  401. ;! Below are private procs you should never call directly from your code                          ;;
  402. ;;================================================================================================;;
  403. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  404. ;;================================================================================================;;
  405.  
  406.  
  407. ;;================================================================================================;;
  408. proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
  409. ;;------------------------------------------------------------------------------------------------;;
  410. ;? --- TBD ---                                                                                    ;;
  411. ;;------------------------------------------------------------------------------------------------;;
  412. ;> ebx = raw image data                                                                           ;;
  413. ;> edx = image data                                                                               ;;
  414. ;;------------------------------------------------------------------------------------------------;;
  415. ;< --- TBD ---                                                                                    ;;
  416. ;;================================================================================================;;
  417.         mov     esi, ebx
  418.         xor     eax, eax
  419.         mov     [edx + Image.Delay], eax
  420.  
  421.   .next_block:
  422.         dec     [img.decode.gif._length]
  423.         js      .exit_err
  424.         lodsb   ; load gif.Block.Introducer
  425.         cmp     al, gif.Block.Introducer.Extension
  426.         jne     .exit
  427.  
  428.   .ext_block:
  429.         dec     [img.decode.gif._length]
  430.         js      .exit_err
  431.         lodsb   ; load gif.Extension.Label
  432.         cmp     al, gif.Extension.Label.GraphicsControl
  433.         je      .graphics_control_ext
  434. ;       cmp     al, gif.Extension.Label.PlainText
  435. ;       je      .plain_text_ext
  436. ;       cmp     al, gif.Extension.Label.Comment
  437. ;       je      .comment_ext
  438. ;       cmp     al, gif.Extension.Label.Application
  439. ;       je      .application_ext
  440. ; skip all other extensions
  441.   .skip_ext:
  442.         dec     [img.decode.gif._length]
  443.         js      .exit_err
  444.         lodsb   ; load BlockSize
  445.   .1:
  446.         test    al, al
  447.         jz      .next_block
  448.         sub     [img.decode.gif._length], eax
  449.         jc      .exit_err
  450.         add     esi, eax
  451.         jmp     .skip_ext
  452.  
  453.   .graphics_control_ext:
  454.         dec     [img.decode.gif._length]
  455.         js      .exit_err
  456.         lodsb   ; load BlockSize; must be sizeof.gif.GraphicsControlExtension
  457.         cmp     al, sizeof.gif.GraphicsControlExtension
  458.         jnz     .1
  459.         sub     [img.decode.gif._length], eax
  460.         jc      .exit_err
  461.         push    edi
  462.         movzx   edi, [esi + gif.GraphicsControlExtension.DelayTime]
  463.         mov     [edx + Image.Delay], edi
  464.         mov     edi, [edx + Image.Extended]
  465.         add     edi, gif.Image.gce
  466.         mov     ecx, eax
  467.         rep     movsb
  468.         pop     edi
  469.         jmp     .skip_ext
  470.  
  471.   .exit_err:
  472.         xor     eax, eax
  473.  
  474.   .exit:
  475.         mov     ebx, esi
  476.         ret
  477. endp
  478.  
  479. ;;================================================================================================;;
  480. proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
  481. ;;------------------------------------------------------------------------------------------------;;
  482. ;? --- TBD ---                                                                                    ;;
  483. ;;------------------------------------------------------------------------------------------------;;
  484. ;> ebx = raw image data                                                                           ;;
  485. ;> edx = image data                                                                               ;;
  486. ;;------------------------------------------------------------------------------------------------;;
  487. ;< --- TBD ---                                                                                    ;;
  488. ;;================================================================================================;;
  489. locals
  490.   width      dd ?
  491.   img_start  dd ?
  492.   img_end    dd ?
  493.   row_end    dd ?
  494.   pass       dd ?
  495.   codesize   dd ?
  496.   compsize   dd ?
  497.   workarea   dd ?
  498.   block_ofs  dd ?
  499.   bit_count  dd ?
  500.   CC         dd ?
  501.   EOI        dd ?
  502. endl
  503.  
  504.         invoke  mem.alloc, 16 * 1024
  505.         mov     [workarea], eax
  506.         or      eax, eax
  507.         jz      .error
  508.  
  509.         mov     ecx, [edx + Image.Width]
  510.         mov     [width], ecx
  511.         mov     eax, [edx + Image.Height]
  512.         imul    eax, ecx
  513.         mov     [img_end], eax
  514.         inc     eax
  515.         mov     [row_end], eax
  516.         and     [pass], 0
  517.         and     dword [img.decode.gif.max_color_child], 0
  518.         mov     eax, [edx + Image.Extended]
  519.         test    [eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
  520.         jz      @f
  521.         mov     [row_end], ecx
  522.  
  523.     @@: mov     esi, ebx
  524.         mov     edi, [edx + Image.Data]
  525.  
  526.         sub     dword [img.decode.gif._length_child], 2
  527.         jc      .error
  528.         movzx   ecx, byte[esi]
  529.         inc     esi
  530.         cmp     cl, 12
  531.         jae     .error
  532.         mov     [codesize], ecx
  533.         inc     [codesize]
  534.         xor     eax, eax
  535.         lodsb                           ; eax - block_count
  536.         sub     [img.decode.gif._length_child], eax
  537.         jc      .error
  538.         add     eax, esi
  539.         push    edi
  540.         mov     edi, [workarea]
  541.         mov     [block_ofs], eax
  542.         mov     [bit_count], 8
  543.         mov     eax, 1
  544.         shl     eax, cl
  545.         mov     [CC], eax
  546.         mov     ecx, eax
  547.         inc     eax
  548.         mov     [EOI], eax
  549.         mov     eax, gif.Null shl 16
  550.   .filltable:
  551.         stosd
  552.         inc     eax
  553.         loop    .filltable
  554.         pop     edi
  555.         mov     [img_start], edi
  556.         add     [img_end], edi
  557.         add     [row_end], edi
  558.   .reinit:
  559.         mov     edx, [EOI]
  560.         inc     edx
  561.         push    [codesize]
  562.         pop     [compsize]
  563.         call    .get_symbol
  564.         cmp     eax, [CC]
  565.         je      .reinit
  566.         call    .output
  567.   .cycle:
  568.         movzx   ebx, ax
  569.         call    .get_symbol
  570.         cmp     eax, [EOI]
  571.         je      .end
  572.         cmp     eax, edx
  573.         ja      .error
  574.         je      .notintable
  575.         cmp     eax, [CC]
  576.         je      .reinit
  577.         call    .output
  578.   .add:
  579.         cmp     edx, 0x00001000
  580.         jae     .cycle
  581.         mov     ecx, [workarea]
  582.         mov     [ecx + edx * 4], ebx
  583.         inc     edx
  584.         cmp     edx, 0x1000
  585.         je      .noinc
  586.         bsr     ebx, edx
  587.         cmp     ebx, [compsize]
  588.         jne     .noinc
  589.         inc     [compsize]
  590.   .noinc:
  591.         jmp     .cycle
  592.   .notintable:
  593.         push    eax
  594.         mov     eax, ebx
  595.         call    .output
  596.         push    ebx
  597.         movzx   eax, bx
  598.         call    .output
  599.         pop     ebx eax
  600.         jmp     .add
  601.   .end:
  602.         mov     edi, [img_end]
  603.         xor     eax, eax
  604.  
  605.   .exit:
  606.         cmp     [workarea], 0
  607.         je      @f
  608.         invoke  mem.free, [workarea]
  609.     @@:
  610.         mov     ebx, [block_ofs]
  611.     @@:
  612.         dec     [img.decode.gif._length_child]
  613.         js      @f
  614.         movzx   eax, byte [ebx]
  615.         inc     ebx
  616.         test    eax, eax
  617.         jz      .ret
  618.         sub     [img.decode.gif._length_child], eax
  619.         jc      @f
  620.         add     ebx, eax
  621.         jmp     @b
  622.  
  623.   .error:
  624.         cmp     [workarea], 0
  625.         je      @f
  626.         invoke  mem.free, [workarea]
  627.     @@: xor     ebx, ebx
  628.   .ret:
  629.         ret
  630.  
  631. ;;------------------------------------------------------------------------------------------------;;
  632.  
  633. img.decode.gif._.process_image.get_symbol:
  634.         mov     ecx, [compsize]
  635.         push    ecx
  636.         xor     eax, eax
  637.  
  638.   .shift:
  639.         dec     [bit_count]
  640.         jns     .loop1
  641.         inc     esi
  642.         cmp     esi, [block_ofs]
  643.         jb      .noblock
  644.         push    eax
  645.         xor     eax, eax
  646.         sub     [img.decode.gif._length_child], 1
  647.         jc      .error_eof
  648.         lodsb
  649.         test    eax, eax
  650.         jnz     .nextbl
  651.   .error_eof:
  652.         add     esp, 12
  653.         jmp     img.decode.gif._.process_image.error
  654.  
  655.   .nextbl:
  656.         sub     [img.decode.gif._length_child], eax
  657.         jc      .error_eof
  658.         add     eax, esi
  659.         mov     [block_ofs], eax
  660.         pop     eax
  661.  
  662.   .noblock:
  663.         mov     [bit_count], 7
  664.  
  665.   .loop1:
  666.         ror     byte[esi], 1
  667.         rcr     eax,1
  668.         loop    .shift
  669.         pop     ecx
  670.         rol     eax, cl
  671.  
  672.   .exit:
  673.         xor     ecx, ecx
  674.         retn
  675.  
  676. ;;------------------------------------------------------------------------------------------------;;
  677.  
  678. img.decode.gif._.process_image.output:
  679.         push    esi eax edx
  680.         mov     edx, [workarea]
  681.  
  682.   .next:
  683.         pushw   [edx + eax * 4]
  684.         mov     ax, [edx + eax * 4 + 2]
  685.         inc     ecx
  686.         cmp     ax, gif.Null
  687.         jnz     .next
  688.         shl     ebx, 16
  689.         mov     bx, [esp]
  690.  
  691.   .loop2:
  692.         pop     ax
  693.         cmp     al, byte [img.decode.gif.cur_color_table_size_child]
  694.         jbe     @f      ; guard against incorrect GIFs
  695.         mov     al, 0
  696.     @@: cmp     al, byte [img.decode.gif.max_color_child]
  697.         jbe     @f
  698.         mov     [img.decode.gif.max_color_child], al
  699.     @@: stosb
  700.  
  701.         cmp     edi, [row_end]
  702.         jb      .norowend
  703.         mov     eax, [width]
  704.         push    eax
  705.         sub     edi, eax
  706.         add     eax, eax
  707.         cmp     [pass], 3
  708.         je      @f
  709.         add     eax, eax
  710.         cmp     [pass], 2
  711.         je      @f
  712.         add     eax, eax
  713.     @@: add     edi, eax
  714.         pop     eax
  715.         cmp     edi, [img_end]
  716.         jb      .nextrow
  717.         mov     edi, [img_start]
  718.         inc     [pass]
  719.         cmp     [pass], 4
  720.         je      .done
  721.         add     edi, eax
  722.         cmp     [pass], 3
  723.         je      @f
  724.         add     edi, eax
  725.         cmp     [pass], 2
  726.         je      @f
  727.         add     edi, eax
  728.         add     edi, eax
  729.     @@:
  730.  
  731.   .nextrow:
  732.         add     eax, edi
  733.         mov     [row_end], eax
  734.         xor     eax, eax
  735.  
  736.   .norowend:
  737.         cmp     edi, [img_end]
  738.         jz      .done
  739.         loop    .loop2
  740.         pop     edx eax esi
  741.         retn
  742.  
  743.   .done:
  744.         lea     esp, [esp+(ecx-1)*2]
  745.         pop     edx eax esi eax
  746.         jmp     img.decode.gif._.process_image.exit
  747.  
  748. endp
  749.  
  750. ;;================================================================================================;;
  751. proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
  752. ;;------------------------------------------------------------------------------------------------;;
  753. ;? Determines whether GIF image occupies the whole logical screen                                 ;;
  754. ;;------------------------------------------------------------------------------------------------;;
  755. ;> eax = extended image data                                                                      ;;
  756. ;> ebx = main image                                                                               ;;
  757. ;;------------------------------------------------------------------------------------------------;;
  758. ;< ZF set <=> image area equals logical screen                                                    ;;
  759. ;;================================================================================================;;
  760.         mov     ebx, [ebx + Image.Extended]
  761.         cmp     [eax + gif.Image.info.Left], 0
  762.         jnz     @f
  763.         cmp     [eax + gif.Image.info.Top], 0
  764.         jnz     @f
  765.         mov     cx, [eax + gif.Image.info.Width]
  766.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  767.         jnz     @f
  768.         mov     cx, [eax + gif.Image.info.Height]
  769.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  770. @@:     retn
  771. endp
  772.  
  773. main_img equ img.decode.gif.main_img
  774. transparent_color equ img.decode.gif.transparent_color
  775. background_color equ img.decode.gif.background_color
  776. prev_num_colors equ img.decode.gif.prev_num_colors
  777. prev_palette equ img.decode.gif.prev_palette
  778. max_color equ img.decode.gif.max_color
  779. prev_img_data equ img.decode.gif.prev_img_data
  780. _data equ img.decode.gif._data
  781. aux_img_data equ img.decode.gif.aux_img_data
  782. aux_img_type equ img.decode.gif.aux_img_type
  783. aux_palette equ img.decode.gif.aux_palette
  784.  
  785. ;;================================================================================================;;
  786. proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
  787. ;;------------------------------------------------------------------------------------------------;;
  788. ;? --- TBD ---                                                                                    ;;
  789. ;;------------------------------------------------------------------------------------------------;;
  790. ;> edx = image data                                                                               ;;
  791. ;;------------------------------------------------------------------------------------------------;;
  792. ;< --- TBD ---                                                                                    ;;
  793. ;;================================================================================================;;
  794.         mov     ebx, [main_img]
  795.         mov     eax, [edx + Image.Extended]
  796.         or      [transparent_color], -1         ; no transparent color
  797.         test    byte [eax + gif.Image.gce.Packed], 1
  798.         jz      @f
  799.         movzx   ecx, byte [eax + gif.Image.gce.ColorIndex]
  800.         mov     [transparent_color], ecx
  801.         cmp     edx, ebx
  802.         jnz     .has_transparency
  803.         shl     ecx, 2
  804.         add     ecx, [edx + Image.Palette]
  805.         push    eax
  806.         mov     eax, [img.decode.gif.options_bgr]
  807.         mov     dword [background_color], eax
  808.         mov     dword [ecx], eax
  809.         pop     eax
  810. @@:
  811.         call    img.decode.gif._.is_logical_screen
  812.         jnz     .has_transparency
  813. ; image is not transparent, so keep it as is
  814.         retn
  815.  
  816. .has_transparency:
  817. ; image has transparent areas, we must superimpose it on the previous
  818.         mov     ecx, [prev_num_colors]
  819.         cmp     ecx, 0x100
  820.         ja      .superimpose_on_rgb
  821. ; create common palette
  822.         sub     esp, 3FCh
  823.         push    eax
  824.         mov     edi, esp
  825.         push    ecx
  826.         mov     esi, [prev_palette]
  827.         rep     movsd
  828.         pop     ecx
  829.         mov     esi, [edx + Image.Palette]
  830.         xor     ebx, ebx
  831.         mov     edi, esp
  832.         sub     esp, 100h
  833. .create_palette_loop:
  834.         push    ecx
  835.         lodsd
  836.         cmp     ebx, [transparent_color]
  837.         jz      .nochange
  838.         cmp     ebx, ecx
  839.         jae     @f
  840.         cmp     eax, [edi+ebx*4]
  841.         jz      .nochange
  842. @@:
  843.         push    edi
  844.         repnz   scasd
  845.         pop     edi
  846.         jnz     .increase_palette
  847.         sub     ecx, [esp]
  848.         not     ecx     ; cl = index of new color in current palette
  849.         jmp     .palette_common
  850. .increase_palette:
  851.         mov     ecx, [esp]
  852.         test    ch, ch
  853.         jnz     .output_to_rgb
  854.         inc     dword [esp]
  855.         mov     [edi+ecx*4], eax
  856.         jmp     .palette_common
  857. .nochange:
  858.         mov     ecx, ebx
  859. .palette_common:
  860.         mov     [ebx+esp+4], cl
  861.         pop     ecx
  862.         inc     ebx
  863.         cmp     ebx, [max_color]
  864.         jbe     .create_palette_loop
  865.         mov     [max_color], ecx
  866. ; if image occupies only part of logical screen, allocate memory for full logical screen
  867.         mov     ebx, [main_img]
  868.         mov     eax, [edx + Image.Extended]
  869.         mov     esi, [edx + Image.Data]
  870.         call    img.decode.gif._.is_logical_screen
  871.         jz      @f
  872.         and     [edx + Image.Data], 0
  873.         push    edx
  874.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  875.         push    eax
  876.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  877.         stdcall img._.resize_data, edx, eax
  878.         pop     edx
  879.         test    eax, eax
  880.         jz      .palette_nomem
  881. @@:
  882. ; copy final palette to Image.Palette
  883.         push    esi esi
  884.         mov     esi, edi
  885.         mov     edi, [edx + Image.Palette]
  886.         mov     ecx, [max_color]
  887.         dec     [max_color]
  888.         rep     movsd
  889.         mov     esi, [prev_img_data]
  890.         mov     edi, [edx + Image.Data]
  891. ; do superimpose, [esp] -> source data, esi -> prev image data
  892. ;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
  893. ;   used palette and final palette, edi -> destination data
  894.         mov     ebx, [edx + Image.Extended]
  895. ; first Top rows are copied from [prev_img_data] or filled with bgr
  896.         movzx   ecx, [ebx + gif.Image.info.Top]
  897.         cmp     ecx, [edx + Image.Height]
  898.         jb      @f
  899.         mov     ecx, [edx + Image.Height]
  900. @@:
  901.         push    ecx
  902.         imul    ecx, [edx + Image.Width]
  903.         call    .rep_movsb_or_stosb
  904.         pop     ecx
  905. ; convert rows
  906.         sub     ecx, [edx + Image.Height]
  907.         neg     ecx
  908.         push    ecx
  909.         cmp     cx, [ebx + gif.Image.info.Height]
  910.         jbe     @f
  911.         mov     cx, [ebx + gif.Image.info.Height]
  912. @@:
  913.         jecxz   .norows
  914. .convert_rows:
  915.         push    ecx
  916.         movzx   ecx, [ebx + gif.Image.info.Left]
  917.         cmp     ecx, [edx + Image.Width]
  918.         jb      @f
  919.         mov     ecx, [edx + Image.Width]
  920. @@:
  921.         push    ecx
  922.         call    .rep_movsb_or_stosb
  923.         pop     ecx
  924.         sub     ecx, [edx + Image.Width]
  925.         neg     ecx
  926.         push    ecx edx
  927.         mov     edx, [esp+16]   ; source data
  928.         cmp     cx, [ebx + gif.Image.info.Width]
  929.         jbe     @f
  930.         mov     cx, [ebx + gif.Image.info.Width]
  931. @@:
  932.         jecxz   .norowsi
  933. .rowsloop:
  934.         movzx   eax, byte [edx]
  935.         inc     edx
  936.         cmp     eax, [transparent_color]
  937.         jz      .rows_transparent
  938.         mov     al, [eax+esp+24]
  939.         stosb
  940.         call    .lodsb
  941.         jmp     @f
  942. .rows_transparent:
  943.         call    .lodsb
  944.         stosb
  945. @@:
  946.         loop    .rowsloop
  947. .norowsi:
  948.         pop     edx ecx
  949.         sub     cx, [ebx + gif.Image.info.Width]
  950.         jbe     @f
  951.         call    .rep_movsb_or_stosb
  952. @@:
  953.         movzx   eax, [ebx + gif.Image.info.Width]
  954.         add     [esp+8], eax
  955.         pop     ecx
  956.         loop    .convert_rows
  957. .norows:
  958.         pop     ecx
  959.         sub     cx, [ebx + gif.Image.info.Height]
  960.         jbe     @f
  961.         imul    ecx, [edx + Image.Width]
  962.         call    .rep_movsb_or_stosb
  963. @@:
  964. ; free old image data if we have allocated new copy
  965.         pop     esi esi
  966.         cmp     esi, [edx + Image.Data]
  967.         jz      @f
  968.         invoke  mem.free, esi
  969. @@:
  970. ; cleanup stack and return
  971.         add     esp, 500h
  972.         retn
  973. .palette_nomem:
  974.         mov     [edx + Image.Data], esi
  975.         jmp     @b
  976.  
  977. .output_to_rgb:
  978.         pop     ecx
  979.         add     esp, 500h
  980. ; compose two palette-based images to one RGB image
  981.         xor     esi, esi
  982.         xchg    esi, [edx + Image.Data]
  983.         push    esi
  984.         mov     ebx, [_data]
  985.         push    [edx + Image.Palette]
  986.         mov     byte [edx + Image.Type], Image.bpp24
  987.         push    edx
  988.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  989.         push    eax
  990.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  991.         stdcall img._.resize_data, edx, eax
  992.         pop     edx
  993.         test    eax, eax
  994.         jz      .convrgb_nomem
  995.         push    esi
  996.         mov     edi, [edx + Image.Data]
  997.         mov     esi, [prev_img_data]
  998.         mov     ebx, [edx + Image.Extended]
  999. ; first Top rows are copied from [prev_img_data] or filled with bgr
  1000.         movzx   ecx, [ebx + gif.Image.info.Top]
  1001.         cmp     ecx, [edx + Image.Height]
  1002.         jb      @f
  1003.         mov     ecx, [edx + Image.Height]
  1004. @@:
  1005.         push    ecx
  1006.         imul    ecx, [edx + Image.Width]
  1007.         call    .convrgb_prev
  1008.         pop     ecx
  1009. ; convert rows
  1010.         sub     ecx, [edx + Image.Height]
  1011.         neg     ecx
  1012.         push    ecx
  1013.         cmp     cx, [ebx + gif.Image.info.Height]
  1014.         jbe     @f
  1015.         mov     cx, [ebx + gif.Image.info.Height]
  1016. @@:
  1017.         jecxz   .convrgb_norows
  1018. .convrgb_convert_rows:
  1019.         push    ecx
  1020.         movzx   ecx, [ebx + gif.Image.info.Left]
  1021.         cmp     ecx, [edx + Image.Width]
  1022.         jb      @f
  1023.         mov     ecx, [edx + Image.Width]
  1024. @@:
  1025.         push    ecx
  1026.         call    .convrgb_prev
  1027.         pop     ecx
  1028.         sub     ecx, [edx + Image.Width]
  1029.         neg     ecx
  1030.         push    ecx edx
  1031.         mov     edx, [esp+16]   ; source data
  1032.         cmp     cx, [ebx + gif.Image.info.Width]
  1033.         jbe     @f
  1034.         mov     cx, [ebx + gif.Image.info.Width]
  1035. @@:
  1036.         jecxz   .convrgb_norowsi
  1037. .convrgb_rowsloop:
  1038.         movzx   eax, byte [edx]
  1039.         inc     edx
  1040.         cmp     eax, [transparent_color]
  1041.         jz      .convrgb_rows_transparent
  1042.         shl     eax, 2
  1043.         add     eax, [esp+20]   ; source palette
  1044.         mov     eax, [eax]
  1045.         stosw
  1046.         shr     eax, 16
  1047.         stosb
  1048.         call    .convrgb_lodsb
  1049.         jmp     @f
  1050. .convrgb_rows_transparent:
  1051.         call    .convrgb_lodsb
  1052.         stosw
  1053.         shr     eax, 16
  1054.         stosb
  1055. @@:
  1056.         loop    .convrgb_rowsloop
  1057. .convrgb_norowsi:
  1058.         pop     edx ecx
  1059.         sub     cx, [ebx + gif.Image.info.Width]
  1060.         jbe     @f
  1061.         call    .convrgb_prev
  1062. @@:
  1063.         movzx   eax, [ebx + gif.Image.info.Width]
  1064.         add     [esp+8], eax
  1065.         pop     ecx
  1066.         loop    .convrgb_convert_rows
  1067. .convrgb_norows:
  1068.         pop     ecx
  1069.         sub     cx, [ebx + gif.Image.info.Height]
  1070.         jbe     @f
  1071.         imul    ecx, [edx + Image.Width]
  1072.         call    .convrgb_prev
  1073. @@:
  1074. ; free old image data
  1075.         pop     esi esi ;esi
  1076.         invoke  mem.free;, esi
  1077.         retn
  1078. .convrgb_nomem:
  1079.         pop     esi esi
  1080.         retn
  1081.  
  1082. .superimpose_on_rgb:
  1083. ; previous image is RGB, new image has transparent areas
  1084.         xor     esi, esi
  1085.         xchg    esi, [edx + Image.Data]
  1086.         push    esi
  1087.         mov     ebx, [_data]
  1088.         push    [edx + Image.Palette]
  1089.         mov     byte [edx + Image.Type], Image.bpp24
  1090.         push    edx
  1091.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1092.         push    eax
  1093.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1094.         stdcall img._.resize_data, edx, eax
  1095.         pop     edx
  1096.         test    eax, eax
  1097.         jz      .rgb_nomem
  1098.         push    esi
  1099.         mov     edi, [edx + Image.Data]
  1100.         mov     esi, [prev_img_data]
  1101.         mov     ebx, [edx + Image.Extended]
  1102. ; first Top rows are copied from [prev_img_data] or filled with bgr
  1103.         movzx   ecx, [ebx + gif.Image.info.Top]
  1104.         cmp     ecx, [edx + Image.Height]
  1105.         jb      @f
  1106.         mov     ecx, [edx + Image.Height]
  1107. @@:
  1108.         push    ecx
  1109.         lea     ecx, [ecx*3]
  1110.         imul    ecx, [edx + Image.Width]
  1111.         rep     movsb
  1112.         pop     ecx
  1113. ; convert rows
  1114.         sub     ecx, [edx + Image.Height]
  1115.         neg     ecx
  1116.         push    ecx
  1117.         cmp     cx, [ebx + gif.Image.info.Height]
  1118.         jbe     @f
  1119.         mov     cx, [ebx + gif.Image.info.Height]
  1120. @@:
  1121.         jecxz   .rgb_norows
  1122. .rgb_convert_rows:
  1123.         push    ecx
  1124.         movzx   ecx, [ebx + gif.Image.info.Left]
  1125.         cmp     ecx, [edx + Image.Width]
  1126.         jb      @f
  1127.         mov     ecx, [edx + Image.Width]
  1128. @@:
  1129.         push    ecx
  1130.         lea     ecx, [ecx*3]
  1131.         rep     movsb
  1132.         pop     ecx
  1133.         sub     ecx, [edx + Image.Width]
  1134.         neg     ecx
  1135.         push    ecx edx
  1136.         mov     edx, [esp+16]   ; source data
  1137.         cmp     cx, [ebx + gif.Image.info.Width]
  1138.         jbe     @f
  1139.         mov     cx, [ebx + gif.Image.info.Width]
  1140. @@:
  1141.         jecxz   .rgb_norowsi
  1142. .rgb_rowsloop:
  1143.         movzx   eax, byte [edx]
  1144.         inc     edx
  1145.         cmp     eax, [transparent_color]
  1146.         jz      .rgb_rows_transparent
  1147.         shl     eax, 2
  1148.         add     eax, [esp+20]   ; source palette
  1149.         mov     eax, [eax]
  1150.         stosw
  1151.         shr     eax, 16
  1152.         stosb
  1153.         add     esi, 3
  1154.         jmp     @f
  1155. .rgb_rows_transparent:
  1156.         movsb
  1157.         movsb
  1158.         movsb
  1159. @@:
  1160.         loop    .rgb_rowsloop
  1161. .rgb_norowsi:
  1162.         pop     edx ecx
  1163.         sub     cx, [ebx + gif.Image.info.Width]
  1164.         jbe     @f
  1165.         lea     ecx, [ecx*3]
  1166.         rep     movsb
  1167. @@:
  1168.         movzx   eax, [ebx + gif.Image.info.Width]
  1169.         add     [esp+8], eax
  1170.         pop     ecx
  1171.         loop    .rgb_convert_rows
  1172. .rgb_norows:
  1173.         pop     ecx
  1174.         sub     cx, [ebx + gif.Image.info.Height]
  1175.         jbe     @f
  1176.         imul    ecx, [edx + Image.Width]
  1177.         lea     ecx, [ecx*3]
  1178.         rep     movsb
  1179. @@:
  1180. ; free old image data
  1181.         pop     esi esi ;esi
  1182.         invoke  mem.free;, esi
  1183.         retn
  1184. .rgb_nomem:
  1185.         pop     esi esi
  1186.         retn
  1187.  
  1188. .lodsb:
  1189.         xor     eax, eax
  1190.         test    esi, esi
  1191.         jz      @f
  1192.         lodsb
  1193. @@:     retn
  1194.  
  1195. .rep_movsb_or_stosb:
  1196.         test    esi, esi
  1197.         jz      .rmos1
  1198.         rep     movsb
  1199.         jmp     .rmos2
  1200. .rmos1: xor     eax, eax        ; background index in final palette is 0 in bgr mode
  1201.         rep     stosb
  1202. .rmos2: retn
  1203.  
  1204. .convrgb_prev:
  1205.         jecxz   .convrgb_noprev
  1206.         test    esi, esi
  1207.         jz      .convrgb_prev_bgr
  1208. @@:
  1209.         xor     eax, eax
  1210.         lodsb
  1211.         shl     eax, 2
  1212.         add     eax, [prev_palette]
  1213.         mov     eax, [eax]
  1214.         stosw
  1215.         shr     eax, 16
  1216.         stosb
  1217.         loop    @b
  1218.         retn
  1219. .convrgb_prev_bgr:
  1220. @@:
  1221.         mov     eax, [background_color]
  1222.         stosw
  1223.         shr     eax, 16
  1224.         stosb
  1225.         loop    @b
  1226. .convrgb_noprev:
  1227.         retn
  1228. .convrgb_lodsb:
  1229.         xor     eax, eax
  1230.         test    esi, esi
  1231.         jz      @f
  1232.         lodsb
  1233.         shl     eax, 2
  1234.         add     eax, [prev_palette]
  1235.         mov     eax, [eax]
  1236.         retn
  1237. @@:     mov     eax, [background_color]
  1238.         retn
  1239.  
  1240. endp
  1241.  
  1242. ;;================================================================================================;;
  1243. proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
  1244. ;;------------------------------------------------------------------------------------------------;;
  1245. ;? --- TBD ---                                                                                    ;;
  1246. ;;------------------------------------------------------------------------------------------------;;
  1247. ;> edx = image data                                                                               ;;
  1248. ;;------------------------------------------------------------------------------------------------;;
  1249. ;< --- TBD ---                                                                                    ;;
  1250. ;;================================================================================================;;
  1251.         mov     ebx, [edx + Image.Extended]
  1252.         mov     al, [ebx + gif.Image.gce.Packed]
  1253.         shr     al, 2
  1254.         and     al, 7
  1255.         cmp     al, 2
  1256.         jz      .background
  1257.         cmp     al, 3
  1258.         jz      .previous
  1259. ; don't dispose - set prev_img and related vars to current image
  1260.         mov     eax, [edx + Image.Data]
  1261.         mov     [prev_img_data], eax
  1262.         cmp     [edx + Image.Type], Image.bpp8i
  1263.         jnz     @f
  1264.         mov     eax, [max_color]
  1265.         inc     eax
  1266.         mov     [prev_num_colors], eax
  1267.         mov     eax, [edx + Image.Palette]
  1268.         mov     [prev_palette], eax
  1269.         retn
  1270. @@:
  1271.         or      [prev_num_colors], -1
  1272.         and     [prev_palette], 0
  1273. .previous:
  1274.         retn
  1275. .background:
  1276.         cmp     [prev_img_data], 0
  1277.         jz      .bgr_full
  1278.         mov     ebx, [main_img]
  1279.         mov     eax, [edx + Image.Extended]
  1280.         call    img.decode.gif._.is_logical_screen
  1281.         jnz     @f
  1282. .bgr_full:
  1283.         xor     eax, eax
  1284.         mov     [prev_img_data], eax
  1285.         inc     eax
  1286.         mov     [prev_num_colors], eax
  1287.         lea     eax, [background_color]
  1288.         mov     [prev_palette], eax
  1289.         retn
  1290. @@:
  1291.         cmp     [prev_num_colors], 0x100
  1292.         ja      .rgb
  1293.         mov     eax, [background_color]
  1294.         mov     edi, [prev_palette]
  1295.         mov     ecx, [prev_num_colors]
  1296.         repnz   scasd
  1297.         jz      .palette_ok
  1298.         cmp     [prev_num_colors], 0x100
  1299.         jz      .convert_rgb
  1300.         push    1
  1301.         pop     eax
  1302.         stdcall img.decode.gif._.alloc_aux_img
  1303.         test    eax, eax
  1304.         jz      .previous
  1305.         mov     ecx, [prev_num_colors]
  1306.         mov     esi, [prev_palette]
  1307.         call    img.decode.gif._.alloc_aux_palette
  1308.         test    eax, eax
  1309.         jz      .previous
  1310.         mov     [prev_palette], eax
  1311.         mov     eax, [background_color]
  1312.         stosd
  1313.         mov     eax, [prev_num_colors]  ; eax = index of background color
  1314.         inc     [prev_num_colors]
  1315.         jmp     .bpp8_common
  1316. .palette_ok:
  1317.         push    1
  1318.         pop     eax
  1319.         stdcall img.decode.gif._.alloc_aux_img
  1320.         test    eax, eax
  1321.         jz      .previous
  1322.         sub     edi, [prev_palette]
  1323.         shr     edi, 2
  1324.         lea     eax, [edi-1]    ; eax = index of background color
  1325. .bpp8_common:
  1326.         push    eax
  1327.         mov     ebx, [_data]
  1328.         mov     esi, [prev_img_data]
  1329.         mov     edi, [aux_img_data]
  1330.         mov     [prev_img_data], edi
  1331.         cmp     esi, edi
  1332.         jz      @f
  1333.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1334.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1335.         imul    ecx, eax
  1336.         push    edi
  1337.         rep     movsb
  1338.         pop     edi
  1339. @@:
  1340.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1341.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1342.         mov     edx, [edx + Image.Extended]
  1343.         movzx   ecx, [edx + gif.Image.info.Top]
  1344.         sub     esi, ecx
  1345.         jbe     .bpp8_ret
  1346.         imul    ecx, eax
  1347.         add     edi, ecx
  1348.         cmp     si, [edx + gif.Image.info.Height]
  1349.         jb      @f
  1350.         mov     si, [edx + gif.Image.info.Height]
  1351. @@:
  1352.         movzx   ecx, [edx + gif.Image.info.Left]
  1353.         sub     eax, ecx
  1354.         jbe     .bpp8_ret
  1355.         add     edi, ecx
  1356.         cmp     ax, [edx + gif.Image.info.Width]
  1357.         jb      @f
  1358.         mov     ax, [edx + gif.Image.info.Width]
  1359. @@:
  1360.         xchg    eax, ecx
  1361.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1362.         sub     edx, ecx
  1363.         pop     eax
  1364. @@:
  1365.         push    ecx
  1366.         rep     stosb
  1367.         pop     ecx
  1368.         add     edi, edx
  1369.         dec     esi
  1370.         jnz     @b
  1371.         push    eax
  1372. .bpp8_ret:
  1373.         pop     eax
  1374.         retn
  1375. .convert_rgb:
  1376.         push    3
  1377.         pop     eax
  1378.         stdcall img.decode.gif._.alloc_aux_img
  1379.         test    eax, eax
  1380.         jz      .previous
  1381.         or      [prev_num_colors], -1
  1382.         mov     ebx, [_data]
  1383.         mov     esi, [prev_img_data]
  1384.         mov     edi, [aux_img_data]
  1385.         mov     [prev_img_data], edi
  1386.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1387.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1388.         imul    ecx, eax
  1389.         push    edx
  1390.         xor     edx, edx
  1391.         xchg    edx, [prev_palette]
  1392.         add     edi, ecx
  1393.         add     esi, ecx
  1394.         add     edi, ecx
  1395.         add     edi, ecx
  1396. @@:
  1397.         dec     esi
  1398.         movzx   eax, byte [esi]
  1399.         mov     eax, [eax*4+edx]
  1400.         sub     edi, 3
  1401.         mov     [edi], ax
  1402.         shr     eax, 16
  1403.         mov     [edi+2], al
  1404.         loop    @b
  1405.         pop     edx
  1406.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1407.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1408.         mov     edx, [edx + Image.Extended]
  1409.         movzx   ecx, [edx + gif.Image.info.Top]
  1410.         sub     esi, ecx
  1411.         jbe     .convert_rgb_ret
  1412.         imul    ecx, eax
  1413.         lea     ecx, [ecx*3]
  1414.         add     edi, ecx
  1415.         cmp     si, [edx + gif.Image.info.Height]
  1416.         jb      @f
  1417.         mov     si, [edx + gif.Image.info.Height]
  1418. @@:
  1419.         movzx   ecx, [edx + gif.Image.info.Left]
  1420.         sub     eax, ecx
  1421.         jbe     .convert_rgb_ret
  1422.         lea     ecx, [ecx*3]
  1423.         add     edi, ecx
  1424.         cmp     ax, [edx + gif.Image.info.Width]
  1425.         jb      @f
  1426.         mov     ax, [edx + gif.Image.info.Width]
  1427. @@:
  1428.         xchg    eax, ecx
  1429.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1430.         sub     edx, ecx
  1431.         mov     eax, [background_color]
  1432.         lea     edx, [edx*3]
  1433. .convert_rgb_loop:
  1434.         push    ecx
  1435. @@:
  1436.         stosw
  1437.         shr     eax, 16
  1438.         stosb
  1439.         loop    @b
  1440.         pop     ecx
  1441.         add     edi, edx
  1442.         dec     esi
  1443.         jnz     .convert_rgb_loop
  1444. .convert_rgb_ret:
  1445.         retn
  1446. .rgb:
  1447.         push    3
  1448.         pop     eax
  1449.         stdcall img.decode.gif._.alloc_aux_img
  1450.         test    eax, eax
  1451.         jz      .previous
  1452.         or      [prev_num_colors], -1
  1453.         and     [prev_palette], 0
  1454.         mov     ebx, [_data]
  1455.         mov     esi, [prev_img_data]
  1456.         mov     edi, [aux_img_data]
  1457.         mov     [prev_img_data], edi
  1458.         cmp     esi, edi
  1459.         jz      @f
  1460.         movzx   ecx, [ebx + gif.Header.lsd.ScreenHeight]
  1461.         push    ecx
  1462.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1463.         imul    ecx, eax
  1464.         lea     ecx, [ecx*3]
  1465.         push    edi
  1466.         rep     movsb
  1467.         pop     edi
  1468.         pop     esi
  1469.         mov     edx, [edx + Image.Extended]
  1470.         movzx   ecx, [edx + gif.Image.info.Top]
  1471.         sub     esi, ecx
  1472.         jbe     .rgb_ret
  1473.         imul    ecx, eax
  1474.         lea     ecx, [ecx*3]
  1475.         add     edi, ecx
  1476.         cmp     si, [edx + gif.Image.info.Height]
  1477.         jb      @f
  1478.         mov     si, [edx + gif.Image.info.Height]
  1479. @@:
  1480.         movzx   ecx, [edx + gif.Image.info.Left]
  1481.         sub     eax, ecx
  1482.         jbe     .rgb_ret
  1483.         lea     ecx, [ecx*3]
  1484.         add     edi, ecx
  1485.         cmp     ax, [edx + gif.Image.info.Width]
  1486.         jb      @f
  1487.         mov     ax, [edx + gif.Image.info.Width]
  1488. @@:
  1489.         xchg    eax, ecx
  1490.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1491.         sub     edx, ecx
  1492.         mov     eax, [background_color]
  1493.         lea     edx, [edx*3]
  1494. .rgb_loop:
  1495.         push    ecx
  1496. @@:
  1497.         stosw
  1498.         shr     eax, 16
  1499.         stosb
  1500.         loop    @b
  1501.         pop     ecx
  1502.         add     edi, edx
  1503.         dec     esi
  1504.         jnz     .rgb_loop
  1505. .rgb_ret:
  1506.         retn
  1507.  
  1508. endp
  1509.  
  1510. ;;================================================================================================;;
  1511. proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
  1512. ;;------------------------------------------------------------------------------------------------;;
  1513. ;? Allocate auxiliary memory for previous image                                                   ;;
  1514. ;;------------------------------------------------------------------------------------------------;;
  1515. ;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
  1516. ;;------------------------------------------------------------------------------------------------;;
  1517. ;< eax = [aux_img_data]                                                                           ;;
  1518. ;;================================================================================================;;
  1519.         cmp     [aux_img_type], eax
  1520.         jae     @f
  1521.         push    edx eax
  1522.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  1523.         mul     ecx
  1524.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  1525.         mul     ecx
  1526.         invoke  mem.realloc, [aux_img_data], eax
  1527.         pop     ecx edx
  1528.         test    eax, eax
  1529.         jz      @f
  1530.         mov     [aux_img_type], ecx
  1531.         mov     [aux_img_data], eax
  1532. @@:     retn
  1533.  
  1534. endp
  1535.  
  1536. ;;================================================================================================;;
  1537. proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
  1538. ;;------------------------------------------------------------------------------------------------;;
  1539. ;? Allocate and fill aux_palette                                                                  ;;
  1540. ;;------------------------------------------------------------------------------------------------;;
  1541. ;> esi -> palette, ecx = palette size                                                             ;;
  1542. ;;------------------------------------------------------------------------------------------------;;
  1543. ;< [aux_palette] set                                                                              ;;
  1544. ;;================================================================================================;;
  1545.         mov     eax, [aux_palette]
  1546.         test    eax, eax
  1547.         jnz     @f
  1548.         push    edx ecx
  1549.         invoke  mem.alloc, 0x400
  1550.         pop     ecx edx
  1551.         test    eax, eax
  1552.         jz      .ret
  1553.         mov     [aux_palette], eax
  1554. @@:
  1555.         mov     edi, eax
  1556.         rep     movsd
  1557. .ret:
  1558.         retn
  1559.  
  1560. endp
  1561.  
  1562. restore main_img
  1563. restore transparent_color
  1564. restore background_color
  1565. restore prev_num_colors
  1566. restore prev_palette
  1567. restore max_color
  1568. restore prev_img_data
  1569. restore _data
  1570. restore aux_img_data
  1571. restore aux_img_type
  1572. restore aux_palette
  1573.  
  1574. ;;================================================================================================;;
  1575. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1576. ;;================================================================================================;;
  1577. ;! Below is private data you should never use directly from your code                             ;;
  1578. ;;================================================================================================;;
  1579. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1580. ;;================================================================================================;;
  1581.  
  1582.  
  1583. ;
  1584.