Subversion Repositories Kolibri OS

Rev

Rev 1079 | Rev 1118 | 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, 14 local variables
  117. img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*14
  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.bpp8
  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     [ebx + gif.Image.gce.DelayTime], 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.bpp8
  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, [img_end]
  702.         jz      .done
  703.         cmp     edi, [row_end]
  704.         jb      .norowend
  705.         mov     eax, [width]
  706.         push    eax
  707.         sub     edi, eax
  708.         add     eax, eax
  709.         cmp     [pass], 3
  710.         je      @f
  711.         add     eax, eax
  712.         cmp     [pass], 2
  713.         je      @f
  714.         add     eax, eax
  715.     @@: add     edi, eax
  716.         pop     eax
  717.         cmp     edi, [img_end]
  718.         jb      .nextrow
  719.         mov     edi, [img_start]
  720.         inc     [pass]
  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.         loop    .loop2
  738.         pop     edx eax esi
  739.         retn
  740.  
  741.   .done:
  742.         lea     esp, [esp+(ecx-1)*2]
  743.         pop     edx eax esi eax
  744.         jmp     img.decode.gif._.process_image.exit
  745.  
  746. endp
  747.  
  748. ;;================================================================================================;;
  749. proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
  750. ;;------------------------------------------------------------------------------------------------;;
  751. ;? Determines whether GIF image occupies the whole logical screen                                 ;;
  752. ;;------------------------------------------------------------------------------------------------;;
  753. ;> eax = extended image data                                                                      ;;
  754. ;> ebx = main image                                                                               ;;
  755. ;;------------------------------------------------------------------------------------------------;;
  756. ;< ZF set <=> image area equals logical screen                                                    ;;
  757. ;;================================================================================================;;
  758.         mov     ebx, [ebx + Image.Extended]
  759.         cmp     [eax + gif.Image.info.Left], 0
  760.         jnz     @f
  761.         cmp     [eax + gif.Image.info.Top], 0
  762.         jnz     @f
  763.         mov     cx, [eax + gif.Image.info.Width]
  764.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  765.         jnz     @f
  766.         mov     cx, [eax + gif.Image.info.Height]
  767.         cmp     cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  768. @@:     retn
  769. endp
  770.  
  771. main_img equ img.decode.gif.main_img
  772. transparent_color equ img.decode.gif.transparent_color
  773. background_color equ img.decode.gif.background_color
  774. prev_num_colors equ img.decode.gif.prev_num_colors
  775. prev_palette equ img.decode.gif.prev_palette
  776. max_color equ img.decode.gif.max_color
  777. prev_img_data equ img.decode.gif.prev_img_data
  778. _data equ img.decode.gif._data
  779. aux_img_data equ img.decode.gif.aux_img_data
  780. aux_img_type equ img.decode.gif.aux_img_type
  781. aux_palette equ img.decode.gif.aux_palette
  782.  
  783. ;;================================================================================================;;
  784. proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
  785. ;;------------------------------------------------------------------------------------------------;;
  786. ;? --- TBD ---                                                                                    ;;
  787. ;;------------------------------------------------------------------------------------------------;;
  788. ;> edx = image data                                                                               ;;
  789. ;;------------------------------------------------------------------------------------------------;;
  790. ;< --- TBD ---                                                                                    ;;
  791. ;;================================================================================================;;
  792.         mov     ebx, [main_img]
  793.         mov     eax, [edx + Image.Extended]
  794.         or      [transparent_color], -1         ; no transparent color
  795.         test    byte [eax + gif.Image.gce.Packed], 1
  796.         jz      @f
  797.         movzx   ecx, byte [eax + gif.Image.gce.ColorIndex]
  798.         mov     [transparent_color], ecx
  799.         cmp     edx, ebx
  800.         jnz     .has_transparency
  801.         shl     ecx, 2
  802.         add     ecx, [edx + Image.Palette]
  803.         push    eax
  804.         mov     eax, [img.decode.gif.options_bgr]
  805.         mov     dword [background_color], eax
  806.         mov     dword [ecx], eax
  807.         pop     eax
  808. @@:
  809.         call    img.decode.gif._.is_logical_screen
  810.         jnz     .has_transparency
  811. ; image is not transparent, so keep it as is
  812.         retn
  813.  
  814. .has_transparency:
  815. ; image has transparent areas, we must superimpose it on the previous
  816.         mov     ecx, [prev_num_colors]
  817.         cmp     ecx, 0x100
  818.         ja      .superimpose_on_rgb
  819. ; create common palette
  820.         sub     esp, 3FCh
  821.         push    eax
  822.         mov     edi, esp
  823.         push    ecx
  824.         mov     esi, [prev_palette]
  825.         rep     movsd
  826.         pop     ecx
  827.         mov     esi, [edx + Image.Palette]
  828.         xor     ebx, ebx
  829.         mov     edi, esp
  830.         sub     esp, 100h
  831. .create_palette_loop:
  832.         push    ecx
  833.         lodsd
  834.         cmp     ebx, [transparent_color]
  835.         jz      .nochange
  836.         cmp     ebx, ecx
  837.         jae     @f
  838.         cmp     eax, [edi+ebx*4]
  839.         jz      .nochange
  840. @@:
  841.         push    edi
  842.         repnz   scasd
  843.         pop     edi
  844.         jnz     .increase_palette
  845.         sub     ecx, [esp]
  846.         not     ecx     ; cl = index of new color in current palette
  847.         jmp     .palette_common
  848. .increase_palette:
  849.         mov     ecx, [esp]
  850.         test    ch, ch
  851.         jnz     .output_to_rgb
  852.         inc     dword [esp]
  853.         mov     [edi+ecx*4], eax
  854.         jmp     .palette_common
  855. .nochange:
  856.         mov     ecx, ebx
  857. .palette_common:
  858.         mov     [ebx+esp+4], cl
  859.         pop     ecx
  860.         inc     ebx
  861.         cmp     ebx, [max_color]
  862.         jbe     .create_palette_loop
  863.         mov     [max_color], ecx
  864. ; if image occupies only part of logical screen, allocate memory for full logical screen
  865.         mov     ebx, [main_img]
  866.         mov     eax, [edx + Image.Extended]
  867.         mov     esi, [edx + Image.Data]
  868.         call    img.decode.gif._.is_logical_screen
  869.         jz      @f
  870.         and     [edx + Image.Data], 0
  871.         push    edx
  872.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  873.         push    eax
  874.         movzx   eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  875.         stdcall img._.resize_data, edx, eax
  876.         pop     edx
  877.         test    eax, eax
  878.         jz      .palette_nomem
  879. @@:
  880. ; copy final palette to Image.Palette
  881.         push    esi esi
  882.         mov     esi, edi
  883.         mov     edi, [edx + Image.Palette]
  884.         mov     ecx, [max_color]
  885.         dec     [max_color]
  886.         rep     movsd
  887.         mov     esi, [prev_img_data]
  888.         mov     edi, [edx + Image.Data]
  889. ; do superimpose, [esp] -> source data, esi -> prev image data
  890. ;   (NULL if previous image is filled with background color), esp+8 -> correspondence between
  891. ;   used palette and final palette, edi -> destination data
  892.         mov     ebx, [edx + Image.Extended]
  893. ; first Top rows are copied from [prev_img_data] or filled with bgr
  894.         movzx   ecx, [ebx + gif.Image.info.Top]
  895.         cmp     ecx, [edx + Image.Height]
  896.         jb      @f
  897.         mov     ecx, [edx + Image.Height]
  898. @@:
  899.         push    ecx
  900.         imul    ecx, [edx + Image.Width]
  901.         call    .rep_movsb_or_stosb
  902.         pop     ecx
  903. ; convert rows
  904.         sub     ecx, [edx + Image.Height]
  905.         neg     ecx
  906.         push    ecx
  907.         cmp     cx, [ebx + gif.Image.info.Height]
  908.         jbe     @f
  909.         mov     cx, [ebx + gif.Image.info.Height]
  910. @@:
  911.         jecxz   .norows
  912. .convert_rows:
  913.         push    ecx
  914.         movzx   ecx, [ebx + gif.Image.info.Left]
  915.         cmp     ecx, [edx + Image.Width]
  916.         jb      @f
  917.         mov     ecx, [edx + Image.Width]
  918. @@:
  919.         push    ecx
  920.         call    .rep_movsb_or_stosb
  921.         pop     ecx
  922.         sub     ecx, [edx + Image.Width]
  923.         neg     ecx
  924.         push    ecx edx
  925.         mov     edx, [esp+16]   ; source data
  926.         cmp     cx, [ebx + gif.Image.info.Width]
  927.         jbe     @f
  928.         mov     cx, [ebx + gif.Image.info.Width]
  929. @@:
  930.         jecxz   .norowsi
  931. .rowsloop:
  932.         movzx   eax, byte [edx]
  933.         inc     edx
  934.         cmp     eax, [transparent_color]
  935.         jz      .rows_transparent
  936.         mov     al, [eax+esp+24]
  937.         stosb
  938.         call    .lodsb
  939.         jmp     @f
  940. .rows_transparent:
  941.         call    .lodsb
  942.         stosb
  943. @@:
  944.         loop    .rowsloop
  945. .norowsi:
  946.         pop     edx ecx
  947.         sub     cx, [ebx + gif.Image.info.Width]
  948.         jbe     @f
  949.         call    .rep_movsb_or_stosb
  950. @@:
  951.         movzx   eax, [ebx + gif.Image.info.Width]
  952.         add     [esp+8], eax
  953.         pop     ecx
  954.         loop    .convert_rows
  955. .norows:
  956.         pop     ecx
  957.         sub     cx, [ebx + gif.Image.info.Height]
  958.         jbe     @f
  959.         imul    ecx, [edx + Image.Width]
  960.         call    .rep_movsb_or_stosb
  961. @@:
  962. ; free old image data if we have allocated new copy
  963.         pop     esi esi
  964.         cmp     esi, [edx + Image.Data]
  965.         jz      @f
  966.         invoke  mem.free, esi
  967. @@:
  968. ; cleanup stack and return
  969.         add     esp, 500h
  970.         retn
  971. .palette_nomem:
  972.         mov     [edx + Image.Data], esi
  973.         jmp     @b
  974.  
  975. .output_to_rgb:
  976.         pop     ecx
  977.         add     esp, 500h
  978. ; compose two palette-based images to one RGB image
  979.         xor     esi, esi
  980.         xchg    esi, [edx + Image.Data]
  981.         push    esi
  982.         mov     ebx, [_data]
  983.         push    [edx + Image.Palette]
  984.         mov     byte [edx + Image.Type], Image.bpp24
  985.         push    edx
  986.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  987.         push    eax
  988.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  989.         stdcall img._.resize_data, edx, eax
  990.         pop     edx
  991.         test    eax, eax
  992.         jz      .convrgb_nomem
  993.         push    esi
  994.         mov     edi, [edx + Image.Data]
  995.         mov     esi, [prev_img_data]
  996.         mov     ebx, [edx + Image.Extended]
  997. ; first Top rows are copied from [prev_img_data] or filled with bgr
  998.         movzx   ecx, [ebx + gif.Image.info.Top]
  999.         cmp     ecx, [edx + Image.Height]
  1000.         jb      @f
  1001.         mov     ecx, [edx + Image.Height]
  1002. @@:
  1003.         push    ecx
  1004.         imul    ecx, [edx + Image.Width]
  1005.         call    .convrgb_prev
  1006.         pop     ecx
  1007. ; convert rows
  1008.         sub     ecx, [edx + Image.Height]
  1009.         neg     ecx
  1010.         push    ecx
  1011.         cmp     cx, [ebx + gif.Image.info.Height]
  1012.         jbe     @f
  1013.         mov     cx, [ebx + gif.Image.info.Height]
  1014. @@:
  1015.         jecxz   .convrgb_norows
  1016. .convrgb_convert_rows:
  1017.         push    ecx
  1018.         movzx   ecx, [ebx + gif.Image.info.Left]
  1019.         cmp     ecx, [edx + Image.Width]
  1020.         jb      @f
  1021.         mov     ecx, [edx + Image.Width]
  1022. @@:
  1023.         push    ecx
  1024.         call    .convrgb_prev
  1025.         pop     ecx
  1026.         sub     ecx, [edx + Image.Width]
  1027.         neg     ecx
  1028.         push    ecx edx
  1029.         mov     edx, [esp+16]   ; source data
  1030.         cmp     cx, [ebx + gif.Image.info.Width]
  1031.         jbe     @f
  1032.         mov     cx, [ebx + gif.Image.info.Width]
  1033. @@:
  1034.         jecxz   .convrgb_norowsi
  1035. .convrgb_rowsloop:
  1036.         movzx   eax, byte [edx]
  1037.         inc     edx
  1038.         cmp     eax, [transparent_color]
  1039.         jz      .convrgb_rows_transparent
  1040.         shl     eax, 2
  1041.         add     eax, [esp+20]   ; source palette
  1042.         mov     eax, [eax]
  1043.         stosw
  1044.         shr     eax, 16
  1045.         stosb
  1046.         call    .convrgb_lodsb
  1047.         jmp     @f
  1048. .convrgb_rows_transparent:
  1049.         call    .convrgb_lodsb
  1050.         stosw
  1051.         shr     eax, 16
  1052.         stosb
  1053. @@:
  1054.         loop    .convrgb_rowsloop
  1055. .convrgb_norowsi:
  1056.         pop     edx ecx
  1057.         sub     cx, [ebx + gif.Image.info.Width]
  1058.         jbe     @f
  1059.         call    .convrgb_prev
  1060. @@:
  1061.         movzx   eax, [ebx + gif.Image.info.Width]
  1062.         add     [esp+8], eax
  1063.         pop     ecx
  1064.         loop    .convrgb_convert_rows
  1065. .convrgb_norows:
  1066.         pop     ecx
  1067.         sub     cx, [ebx + gif.Image.info.Height]
  1068.         jbe     @f
  1069.         imul    ecx, [edx + Image.Width]
  1070.         call    .convrgb_prev
  1071. @@:
  1072. ; free old image data
  1073.         pop     esi esi ;esi
  1074.         invoke  mem.free;, esi
  1075.         retn
  1076. .convrgb_nomem:
  1077.         pop     esi esi
  1078.         retn
  1079.  
  1080. .superimpose_on_rgb:
  1081. ; previous image is RGB, new image has transparent areas
  1082.         xor     esi, esi
  1083.         xchg    esi, [edx + Image.Data]
  1084.         push    esi
  1085.         mov     ebx, [_data]
  1086.         push    [edx + Image.Palette]
  1087.         mov     byte [edx + Image.Type], Image.bpp24
  1088.         push    edx
  1089.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1090.         push    eax
  1091.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1092.         stdcall img._.resize_data, edx, eax
  1093.         pop     edx
  1094.         test    eax, eax
  1095.         jz      .rgb_nomem
  1096.         push    esi
  1097.         mov     edi, [edx + Image.Data]
  1098.         mov     esi, [prev_img_data]
  1099.         mov     ebx, [edx + Image.Extended]
  1100. ; first Top rows are copied from [prev_img_data] or filled with bgr
  1101.         movzx   ecx, [ebx + gif.Image.info.Top]
  1102.         cmp     ecx, [edx + Image.Height]
  1103.         jb      @f
  1104.         mov     ecx, [edx + Image.Height]
  1105. @@:
  1106.         push    ecx
  1107.         lea     ecx, [ecx*3]
  1108.         imul    ecx, [edx + Image.Width]
  1109.         rep     movsb
  1110.         pop     ecx
  1111. ; convert rows
  1112.         sub     ecx, [edx + Image.Height]
  1113.         neg     ecx
  1114.         push    ecx
  1115.         cmp     cx, [ebx + gif.Image.info.Height]
  1116.         jbe     @f
  1117.         mov     cx, [ebx + gif.Image.info.Height]
  1118. @@:
  1119.         jecxz   .rgb_norows
  1120. .rgb_convert_rows:
  1121.         push    ecx
  1122.         movzx   ecx, [ebx + gif.Image.info.Left]
  1123.         cmp     ecx, [edx + Image.Width]
  1124.         jb      @f
  1125.         mov     ecx, [edx + Image.Width]
  1126. @@:
  1127.         push    ecx
  1128.         lea     ecx, [ecx*3]
  1129.         rep     movsb
  1130.         pop     ecx
  1131.         sub     ecx, [edx + Image.Width]
  1132.         neg     ecx
  1133.         push    ecx edx
  1134.         mov     edx, [esp+16]   ; source data
  1135.         cmp     cx, [ebx + gif.Image.info.Width]
  1136.         jbe     @f
  1137.         mov     cx, [ebx + gif.Image.info.Width]
  1138. @@:
  1139.         jecxz   .rgb_norowsi
  1140. .rgb_rowsloop:
  1141.         movzx   eax, byte [edx]
  1142.         inc     edx
  1143.         cmp     eax, [transparent_color]
  1144.         jz      .rgb_rows_transparent
  1145.         shl     eax, 2
  1146.         add     eax, [esp+20]   ; source palette
  1147.         mov     eax, [eax]
  1148.         stosw
  1149.         shr     eax, 16
  1150.         stosb
  1151.         add     esi, 3
  1152.         jmp     @f
  1153. .rgb_rows_transparent:
  1154.         movsb
  1155.         movsb
  1156.         movsb
  1157. @@:
  1158.         loop    .rgb_rowsloop
  1159. .rgb_norowsi:
  1160.         pop     edx ecx
  1161.         sub     cx, [ebx + gif.Image.info.Width]
  1162.         jbe     @f
  1163.         lea     ecx, [ecx*3]
  1164.         rep     movsb
  1165. @@:
  1166.         movzx   eax, [ebx + gif.Image.info.Width]
  1167.         add     [esp+8], eax
  1168.         pop     ecx
  1169.         loop    .rgb_convert_rows
  1170. .rgb_norows:
  1171.         pop     ecx
  1172.         sub     cx, [ebx + gif.Image.info.Height]
  1173.         jbe     @f
  1174.         imul    ecx, [edx + Image.Width]
  1175.         lea     ecx, [ecx*3]
  1176.         rep     movsb
  1177. @@:
  1178. ; free old image data
  1179.         pop     esi esi ;esi
  1180.         invoke  mem.free;, esi
  1181.         retn
  1182. .rgb_nomem:
  1183.         pop     esi esi
  1184.         retn
  1185.  
  1186. .lodsb:
  1187.         xor     eax, eax
  1188.         test    esi, esi
  1189.         jz      @f
  1190.         lodsb
  1191. @@:     retn
  1192.  
  1193. .rep_movsb_or_stosb:
  1194.         test    esi, esi
  1195.         jz      .rmos1
  1196.         rep     movsb
  1197.         jmp     .rmos2
  1198. .rmos1: xor     eax, eax        ; background index in final palette is 0 in bgr mode
  1199.         rep     stosb
  1200. .rmos2: retn
  1201.  
  1202. .convrgb_prev:
  1203.         jecxz   .convrgb_noprev
  1204.         test    esi, esi
  1205.         jz      .convrgb_prev_bgr
  1206. @@:
  1207.         xor     eax, eax
  1208.         lodsb
  1209.         shl     eax, 2
  1210.         add     eax, [prev_palette]
  1211.         mov     eax, [eax]
  1212.         stosw
  1213.         shr     eax, 16
  1214.         stosb
  1215.         loop    @b
  1216.         retn
  1217. .convrgb_prev_bgr:
  1218. @@:
  1219.         mov     eax, [background_color]
  1220.         stosw
  1221.         shr     eax, 16
  1222.         stosb
  1223.         loop    @b
  1224. .convrgb_noprev:
  1225.         retn
  1226. .convrgb_lodsb:
  1227.         xor     eax, eax
  1228.         test    esi, esi
  1229.         jz      @f
  1230.         lodsb
  1231.         shl     eax, 2
  1232.         add     eax, [prev_palette]
  1233.         mov     eax, [eax]
  1234.         retn
  1235. @@:     mov     eax, [background_color]
  1236.         retn
  1237.  
  1238. endp
  1239.  
  1240. ;;================================================================================================;;
  1241. proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
  1242. ;;------------------------------------------------------------------------------------------------;;
  1243. ;? --- TBD ---                                                                                    ;;
  1244. ;;------------------------------------------------------------------------------------------------;;
  1245. ;> edx = image data                                                                               ;;
  1246. ;;------------------------------------------------------------------------------------------------;;
  1247. ;< --- TBD ---                                                                                    ;;
  1248. ;;================================================================================================;;
  1249.         mov     ebx, [edx + Image.Extended]
  1250.         mov     al, [ebx + gif.Image.gce.Packed]
  1251.         shr     al, 2
  1252.         and     al, 7
  1253.         cmp     al, 2
  1254.         jz      .background
  1255.         cmp     al, 3
  1256.         jz      .previous
  1257. ; don't dispose - set prev_img and related vars to current image
  1258.         mov     eax, [edx + Image.Data]
  1259.         mov     [prev_img_data], eax
  1260.         cmp     [edx + Image.Type], Image.bpp8
  1261.         jnz     @f
  1262.         mov     eax, [max_color]
  1263.         inc     eax
  1264.         mov     [prev_num_colors], eax
  1265.         mov     eax, [edx + Image.Palette]
  1266.         mov     [prev_palette], eax
  1267.         retn
  1268. @@:
  1269.         or      [prev_num_colors], -1
  1270.         and     [prev_palette], 0
  1271. .previous:
  1272.         retn
  1273. .background:
  1274.         cmp     [prev_img_data], 0
  1275.         jz      .bgr_full
  1276.         mov     ebx, [main_img]
  1277.         mov     eax, [edx + Image.Extended]
  1278.         call    img.decode.gif._.is_logical_screen
  1279.         jnz     @f
  1280. .bgr_full:
  1281.         xor     eax, eax
  1282.         mov     [prev_img_data], eax
  1283.         inc     eax
  1284.         mov     [prev_num_colors], eax
  1285.         lea     eax, [background_color]
  1286.         mov     [prev_palette], eax
  1287.         retn
  1288. @@:
  1289.         cmp     [prev_num_colors], 0x100
  1290.         ja      .rgb
  1291.         mov     eax, [background_color]
  1292.         mov     edi, [prev_palette]
  1293.         mov     ecx, [prev_num_colors]
  1294.         repnz   scasd
  1295.         jz      .palette_ok
  1296.         cmp     [prev_num_colors], 0x100
  1297.         jz      .convert_rgb
  1298.         push    1
  1299.         pop     eax
  1300.         stdcall img.decode.gif._.alloc_aux_img
  1301.         test    eax, eax
  1302.         jz      .previous
  1303.         mov     ecx, [prev_num_colors]
  1304.         mov     esi, [prev_palette]
  1305.         call    img.decode.gif._.alloc_aux_palette
  1306.         test    eax, eax
  1307.         jz      .previous
  1308.         mov     [prev_palette], eax
  1309.         mov     eax, [background_color]
  1310.         stosd
  1311.         mov     eax, [prev_num_colors]  ; eax = index of background color
  1312.         inc     [prev_num_colors]
  1313.         jmp     .bpp8_common
  1314. .palette_ok:
  1315.         push    1
  1316.         pop     eax
  1317.         stdcall img.decode.gif._.alloc_aux_img
  1318.         test    eax, eax
  1319.         jz      .previous
  1320.         sub     edi, [prev_palette]
  1321.         shr     edi, 2
  1322.         lea     eax, [edi-1]    ; eax = index of background color
  1323. .bpp8_common:
  1324.         push    eax
  1325.         mov     ebx, [_data]
  1326.         mov     esi, [prev_img_data]
  1327.         mov     edi, [aux_img_data]
  1328.         mov     [prev_img_data], edi
  1329.         cmp     esi, edi
  1330.         jz      @f
  1331.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1332.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1333.         imul    ecx, eax
  1334.         push    edi
  1335.         rep     movsb
  1336.         pop     edi
  1337. @@:
  1338.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1339.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1340.         mov     edx, [edx + Image.Extended]
  1341.         movzx   ecx, [edx + gif.Image.info.Top]
  1342.         sub     esi, ecx
  1343.         jbe     .bpp8_ret
  1344.         imul    ecx, eax
  1345.         add     edi, ecx
  1346.         cmp     si, [edx + gif.Image.info.Height]
  1347.         jb      @f
  1348.         mov     si, [edx + gif.Image.info.Height]
  1349. @@:
  1350.         movzx   ecx, [edx + gif.Image.info.Left]
  1351.         sub     eax, ecx
  1352.         jbe     .bpp8_ret
  1353.         add     edi, ecx
  1354.         cmp     ax, [edx + gif.Image.info.Width]
  1355.         jb      @f
  1356.         mov     ax, [edx + gif.Image.info.Width]
  1357. @@:
  1358.         xchg    eax, ecx
  1359.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1360.         sub     edx, ecx
  1361.         pop     eax
  1362. @@:
  1363.         push    ecx
  1364.         rep     stosb
  1365.         pop     ecx
  1366.         add     edi, edx
  1367.         dec     esi
  1368.         jnz     @b
  1369.         push    eax
  1370. .bpp8_ret:
  1371.         pop     eax
  1372.         retn
  1373. .convert_rgb:
  1374.         push    3
  1375.         pop     eax
  1376.         stdcall img.decode.gif._.alloc_aux_img
  1377.         test    eax, eax
  1378.         jz      .previous
  1379.         or      [prev_num_colors], -1
  1380.         mov     ebx, [_data]
  1381.         mov     esi, [prev_img_data]
  1382.         mov     edi, [aux_img_data]
  1383.         mov     [prev_img_data], edi
  1384.         movzx   ecx, [ebx + gif.Header.lsd.ScreenWidth]
  1385.         movzx   eax, [ebx + gif.Header.lsd.ScreenHeight]
  1386.         imul    ecx, eax
  1387.         push    edx
  1388.         xor     edx, edx
  1389.         xchg    edx, [prev_palette]
  1390.         add     edi, ecx
  1391.         add     esi, ecx
  1392.         add     edi, ecx
  1393.         add     edi, ecx
  1394. @@:
  1395.         dec     esi
  1396.         movzx   eax, byte [esi]
  1397.         mov     eax, [eax*4+edx]
  1398.         sub     edi, 3
  1399.         mov     [edi], ax
  1400.         shr     eax, 16
  1401.         mov     [edi+2], al
  1402.         loop    @b
  1403.         pop     edx
  1404.         movzx   esi, [ebx + gif.Header.lsd.ScreenHeight]
  1405.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1406.         mov     edx, [edx + Image.Extended]
  1407.         movzx   ecx, [edx + gif.Image.info.Top]
  1408.         sub     esi, ecx
  1409.         jbe     .convert_rgb_ret
  1410.         imul    ecx, eax
  1411.         lea     ecx, [ecx*3]
  1412.         add     edi, ecx
  1413.         cmp     si, [edx + gif.Image.info.Height]
  1414.         jb      @f
  1415.         mov     si, [edx + gif.Image.info.Height]
  1416. @@:
  1417.         movzx   ecx, [edx + gif.Image.info.Left]
  1418.         sub     eax, ecx
  1419.         jbe     .convert_rgb_ret
  1420.         lea     ecx, [ecx*3]
  1421.         add     edi, ecx
  1422.         cmp     ax, [edx + gif.Image.info.Width]
  1423.         jb      @f
  1424.         mov     ax, [edx + gif.Image.info.Width]
  1425. @@:
  1426.         xchg    eax, ecx
  1427.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1428.         sub     edx, ecx
  1429.         mov     eax, [background_color]
  1430.         lea     edx, [edx*3]
  1431. .convert_rgb_loop:
  1432.         push    ecx
  1433. @@:
  1434.         stosw
  1435.         shr     eax, 16
  1436.         stosb
  1437.         loop    @b
  1438.         pop     ecx
  1439.         add     edi, edx
  1440.         dec     esi
  1441.         jnz     .convert_rgb_loop
  1442. .convert_rgb_ret:
  1443.         retn
  1444. .rgb:
  1445.         push    3
  1446.         pop     eax
  1447.         stdcall img.decode.gif._.alloc_aux_img
  1448.         test    eax, eax
  1449.         jz      .previous
  1450.         or      [prev_num_colors], -1
  1451.         and     [prev_palette], 0
  1452.         mov     ebx, [_data]
  1453.         mov     esi, [prev_img_data]
  1454.         mov     edi, [aux_img_data]
  1455.         mov     [prev_img_data], edi
  1456.         cmp     esi, edi
  1457.         jz      @f
  1458.         movzx   ecx, [ebx + gif.Header.lsd.ScreenHeight]
  1459.         push    ecx
  1460.         movzx   eax, [ebx + gif.Header.lsd.ScreenWidth]
  1461.         imul    ecx, eax
  1462.         lea     ecx, [ecx*3]
  1463.         push    edi
  1464.         rep     movsb
  1465.         pop     edi
  1466.         pop     esi
  1467.         mov     edx, [edx + Image.Extended]
  1468.         movzx   ecx, [edx + gif.Image.info.Top]
  1469.         sub     esi, ecx
  1470.         jbe     .rgb_ret
  1471.         imul    ecx, eax
  1472.         lea     ecx, [ecx*3]
  1473.         add     edi, ecx
  1474.         cmp     si, [edx + gif.Image.info.Height]
  1475.         jb      @f
  1476.         mov     si, [edx + gif.Image.info.Height]
  1477. @@:
  1478.         movzx   ecx, [edx + gif.Image.info.Left]
  1479.         sub     eax, ecx
  1480.         jbe     .rgb_ret
  1481.         lea     ecx, [ecx*3]
  1482.         add     edi, ecx
  1483.         cmp     ax, [edx + gif.Image.info.Width]
  1484.         jb      @f
  1485.         mov     ax, [edx + gif.Image.info.Width]
  1486. @@:
  1487.         xchg    eax, ecx
  1488.         movzx   edx, [ebx + gif.Header.lsd.ScreenWidth]
  1489.         sub     edx, ecx
  1490.         mov     eax, [background_color]
  1491.         lea     edx, [edx*3]
  1492. .rgb_loop:
  1493.         push    ecx
  1494. @@:
  1495.         stosw
  1496.         shr     eax, 16
  1497.         stosb
  1498.         loop    @b
  1499.         pop     ecx
  1500.         add     edi, edx
  1501.         dec     esi
  1502.         jnz     .rgb_loop
  1503. .rgb_ret:
  1504.         retn
  1505.  
  1506. endp
  1507.  
  1508. ;;================================================================================================;;
  1509. proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
  1510. ;;------------------------------------------------------------------------------------------------;;
  1511. ;? Allocate auxiliary memory for previous image                                                   ;;
  1512. ;;------------------------------------------------------------------------------------------------;;
  1513. ;> eax = image type: 1 = bpp8, 3 = bpp24                                                          ;;
  1514. ;;------------------------------------------------------------------------------------------------;;
  1515. ;< eax = [aux_img_data]                                                                           ;;
  1516. ;;================================================================================================;;
  1517.         cmp     [aux_img_type], eax
  1518.         jae     @f
  1519.         push    edx eax
  1520.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
  1521.         mul     ecx
  1522.         movzx   ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
  1523.         mul     ecx
  1524.         invoke  mem.realloc, [aux_img_data], eax
  1525.         pop     ecx edx
  1526.         test    eax, eax
  1527.         jz      @f
  1528.         mov     [aux_img_type], ecx
  1529.         mov     [aux_img_data], eax
  1530. @@:     retn
  1531.  
  1532. endp
  1533.  
  1534. ;;================================================================================================;;
  1535. proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
  1536. ;;------------------------------------------------------------------------------------------------;;
  1537. ;? Allocate and fill aux_palette                                                                  ;;
  1538. ;;------------------------------------------------------------------------------------------------;;
  1539. ;> esi -> palette, ecx = palette size                                                             ;;
  1540. ;;------------------------------------------------------------------------------------------------;;
  1541. ;< [aux_palette] set                                                                              ;;
  1542. ;;================================================================================================;;
  1543.         mov     eax, [aux_palette]
  1544.         test    eax, eax
  1545.         jnz     @f
  1546.         push    edx ecx
  1547.         invoke  mem.alloc, 0x400
  1548.         pop     ecx edx
  1549.         test    eax, eax
  1550.         jz      .ret
  1551.         mov     [aux_palette], eax
  1552. @@:
  1553.         mov     edi, eax
  1554.         rep     movsd
  1555. .ret:
  1556.         retn
  1557.  
  1558. endp
  1559.  
  1560. restore main_img
  1561. restore transparent_color
  1562. restore background_color
  1563. restore prev_num_colors
  1564. restore prev_palette
  1565. restore max_color
  1566. restore prev_img_data
  1567. restore _data
  1568. restore aux_img_data
  1569. restore aux_img_type
  1570. restore aux_palette
  1571.  
  1572. ;;================================================================================================;;
  1573. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1574. ;;================================================================================================;;
  1575. ;! Below is private data you should never use directly from your code                             ;;
  1576. ;;================================================================================================;;
  1577. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  1578. ;;================================================================================================;;
  1579.  
  1580.  
  1581. ;
  1582.