Subversion Repositories Kolibri OS

Rev

Rev 783 | Rev 1079 | 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], 6
  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 ;//////////////////////////////////////////////////////////////;;
  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.   img                dd ?
  86.   global_color_table dd ?
  87.   global_color_table_size dd ?
  88. endl
  89.  
  90.         push    ebx
  91.  
  92. ; img.is.gif is called by caller (img.decode)
  93. ;       stdcall img.is.gif, [_data], [_length]
  94. ;       or      eax, eax
  95. ;       jz      .error
  96.  
  97.         mov     [global_color_table_size], 0
  98.         mov     ebx, [_data]
  99.  
  100.         test    [ebx + gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
  101.         jz      @f
  102.         lea     eax, [ebx + sizeof.gif.Header]
  103.         mov     [global_color_table], eax
  104.         mov     cl, [ebx + gif.Header.lsd.Packed]
  105.         and     cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
  106.         shr     cl, gif.LSD.Packed.SizeOfGlobalColorTableShift
  107.         mov     eax, 2
  108.         shl     eax, cl
  109.         mov     [global_color_table_size], eax
  110.         lea     eax, [eax * 3]
  111.         add     ebx, eax
  112.     @@: add     ebx, sizeof.gif.Header
  113.  
  114.         mov     [img], 0
  115.  
  116. ;   @@: cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
  117. ;       jne     .next_image
  118. ;       cmp     byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
  119. ;       jne     .error
  120. ;       add     ebx, sizeof.gif.Extension
  121. ;       stdcall ._.skip_data
  122. ;       mov     ebx, eax
  123. ;       jmp     @b
  124.  
  125.   .next_image:
  126.         stdcall img._.new
  127.         or      eax, eax
  128.         jz      .error
  129.         mov     edx, [img]
  130.         mov     [eax + Image.Previous], edx
  131.         test    edx, edx
  132.         jz      @f
  133.         mov     [edx + Image.Next], eax
  134. @@:
  135.         mov     [img], eax
  136.         mov     edx, eax
  137.         mov     [eax + Image.Type], Image.bpp8
  138.  
  139.         invoke  mem.alloc, sizeof.gif.Image
  140.         or      eax, eax
  141.         jz      .error
  142.         mov     [edx + Image.Extended], eax
  143.  
  144.         stdcall ._.process_extensions
  145.  
  146.         cmp     byte[ebx + gif.Block.Introducer], gif.Block.Introducer.ImageDescriptor
  147.         jne     .error
  148.         movzx   eax, [ebx + gif.ImageDescriptor.Width]
  149.         movzx   ecx, [ebx + gif.ImageDescriptor.Height]
  150.         stdcall img._.resize_data, [img], eax, ecx
  151.         or      eax, eax
  152.         jz      .error
  153.  
  154.         mov     esi, ebx
  155.         mov     edi, [edx + Image.Extended]
  156.         mov     ecx, sizeof.gif.ImageDescriptor
  157.         rep     movsb
  158.  
  159.         mov     edi, [edx + Image.Palette]
  160.         mov     esi, [global_color_table]
  161.         mov     ecx, [global_color_table_size]
  162.         test    [ebx + gif.ImageDescriptor.Packed], gif.ID.Packed.LocalColorTableFlag
  163.         jz      @f
  164.         lea     esi, [ebx + sizeof.gif.ImageDescriptor]
  165.         mov     cl, [ebx + gif.ImageDescriptor.Packed]
  166.         and     cl, gif.ID.Packed.SizeOfLocalColorTableMask
  167.         shr     cl, gif.ID.Packed.SizeOfLocalColorTableShift
  168.         mov     eax, 2
  169.         shl     eax, cl
  170.         mov     ecx, eax
  171.         lea     eax, [eax*3]
  172.         add     ebx, eax
  173. @@:
  174.         lodsd
  175.         dec     esi
  176.         bswap   eax
  177.         shr     eax, 8
  178.         stosd
  179.         loop    @b
  180.         add     ebx, sizeof.gif.ImageDescriptor
  181.         stdcall ._.process_image
  182.  
  183.   .decoded:
  184.         or      eax, eax
  185.         jz      @f
  186.         stdcall img.destroy, [img]
  187.         jmp     .error
  188.        
  189.     @@: mov     eax, [img]
  190.         ret
  191.  
  192.   .error:
  193.         mov     eax, [img]
  194.         test    eax, eax
  195.         jz      @f
  196.         stdcall img.destroy, eax
  197. @@:
  198.         xor     eax, eax
  199.         pop     ebx
  200.         ret
  201. endp
  202.  
  203. ;;================================================================================================;;
  204. proc img.encode.gif _img, _p_length ;/////////////////////////////////////////////////////////////;;
  205. ;;------------------------------------------------------------------------------------------------;;
  206. ;? Encode image into raw data in GIF format                                                       ;;
  207. ;;------------------------------------------------------------------------------------------------;;
  208. ;> _img = pointer to image                                                                        ;;
  209. ;;------------------------------------------------------------------------------------------------;;
  210. ;< eax = 0 (error) or pointer to encoded data                                                     ;;
  211. ;< _p_length = encoded data length                                                                ;;
  212. ;;================================================================================================;;
  213.         xor     eax, eax
  214.         ret
  215. endp
  216.  
  217.  
  218. ;;================================================================================================;;
  219. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  220. ;;================================================================================================;;
  221. ;! Below are private procs you should never call directly from your code                          ;;
  222. ;;================================================================================================;;
  223. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  224. ;;================================================================================================;;
  225.  
  226.  
  227. ;;================================================================================================;;
  228. proc img.decode.gif._.skip_data ;/////////////////////////////////////////////////////////////////;;
  229. ;;------------------------------------------------------------------------------------------------;;
  230. ;? --- TBD ---                                                                                    ;;
  231. ;;------------------------------------------------------------------------------------------------;;
  232. ;> ebx = pointer to data blocks array                                                             ;;
  233. ;;------------------------------------------------------------------------------------------------;;
  234. ;< eax = pointer to data right after data blocks array                                            ;;
  235. ;;================================================================================================;;
  236.         push    ecx
  237.         xor     ecx, ecx
  238.     @@: mov     cl, [esi]
  239.         or      cl, cl
  240.         jz      @f
  241.         lea     esi, [esi + ecx + 1]
  242.         jmp     @b
  243.     @@: pop     ecx
  244.         ret
  245. endp
  246.  
  247. ;;================================================================================================;;
  248. proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
  249. ;;------------------------------------------------------------------------------------------------;;
  250. ;? --- TBD ---                                                                                    ;;
  251. ;;------------------------------------------------------------------------------------------------;;
  252. ;> ebx = raw image data                                                                           ;;
  253. ;> edx = image data                                                                               ;;
  254. ;;------------------------------------------------------------------------------------------------;;
  255. ;< --- TBD ---                                                                                    ;;
  256. ;;================================================================================================;;
  257.         push    edx
  258.         mov     esi, ebx
  259.  
  260.   .next_block:
  261.         mov     al, [esi + gif.Block.Introducer]
  262.         cmp     al, gif.Block.Introducer.Extension
  263.         je      .ext_block
  264. ;       cmp     al, gif.Block.Introducer.ImageDescriptor
  265. ;       je      .exit
  266. ;       cmp     al, gif.Block.Introducer.EndOfFile
  267. ;       je      .exit
  268.         jmp     .exit
  269.  
  270.   .ext_block:
  271.         mov     al, [esi + gif.Extension.Label]
  272.         cmp     al, gif.Extension.Label.PlainText
  273.         je      .plain_text_ext
  274.         cmp     al, gif.Extension.Label.GraphicsControl
  275.         je      .graphics_control_ext
  276.         cmp     al, gif.Extension.Label.Comment
  277.         je      .comment_ext
  278.         cmp     al, gif.Extension.Label.Application
  279.         je      .application_ext
  280.         jmp     .exit
  281.  
  282.   .plain_text_ext:
  283.         add     esi, gif.PlainTextExtension.PlainTextData
  284.         stdcall img.decode.gif._.skip_data
  285.         jmp     .next_ext_block
  286.  
  287.   .graphics_control_ext:
  288.         push    edi
  289.         mov     edi, [edx + Image.Extended]
  290.         add     edi, gif.Image.gce
  291.         mov     ecx, sizeof.gif.GraphicsControlExtension
  292.         rep     movsb
  293.         pop     edi
  294.         jmp     .next_ext_block
  295.  
  296.   .comment_ext:
  297.         add     esi, gif.CommentExtension.CommentData
  298.         stdcall img.decode.gif._.skip_data
  299.         jmp     .next_ext_block
  300.  
  301.   .application_ext:
  302.         add     esi, gif.ApplicationExtension.ApplicationData
  303.         stdcall img.decode.gif._.skip_data
  304.         jmp     .next_ext_block
  305.  
  306.   .next_ext_block:
  307.         mov     al, [esi + gif.Block.Introducer]
  308.         cmp     al, gif.Block.Introducer.EndOfData
  309.         jne     .exit
  310.         inc     esi
  311.         jmp     .next_block
  312.  
  313.   .exit:
  314.         mov     ebx, esi
  315.         pop     edx
  316.         ret
  317. endp
  318.  
  319. ;;================================================================================================;;
  320. proc img.decode.gif._.process_image ;/////////////////////////////////////////////////////////////;;
  321. ;;------------------------------------------------------------------------------------------------;;
  322. ;? --- TBD ---                                                                                    ;;
  323. ;;------------------------------------------------------------------------------------------------;;
  324. ;> ebx = raw image data                                                                           ;;
  325. ;> edx = image data                                                                               ;;
  326. ;;------------------------------------------------------------------------------------------------;;
  327. ;< --- TBD ---                                                                                    ;;
  328. ;;================================================================================================;;
  329. locals
  330.   width      dd ?
  331.   img_start  dd ?
  332.   img_end    dd ?
  333.   row_end    dd ?
  334.   pass       dd ?
  335.   codesize   dd ?
  336.   compsize   dd ?
  337.   workarea   dd ?
  338.   block_ofs  dd ?
  339.   bit_count  dd ?
  340.   CC         dd ?
  341.   EOI        dd ?
  342. endl
  343.  
  344.         invoke  mem.alloc, 16 * 1024
  345.         mov     [workarea], eax
  346.         or      eax, eax
  347.         jz      .error
  348.  
  349.         mov     ecx, [edx + Image.Width]
  350.         mov     [width], ecx
  351.         mov     eax, [edx + Image.Height]
  352.         imul    eax, ecx
  353.         mov     [img_end], eax
  354.         inc     eax
  355.         mov     [row_end], eax
  356.         and     [pass], 0
  357.         mov     eax, [edx + Image.Extended]
  358.         test    [eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
  359.         jz      @f
  360.         mov     [row_end], ecx
  361.  
  362.     @@: mov     esi, ebx
  363.         mov     edi, [edx + Image.Data]
  364.  
  365.         push    edi
  366.         movzx   ecx, byte[esi]
  367.         inc     esi
  368.         mov     [codesize], ecx
  369.         inc     [codesize]
  370.         mov     edi, [workarea]
  371.         xor     eax, eax
  372.         lodsb                           ; eax - block_count
  373.         add     eax, esi
  374.         mov     [block_ofs], eax
  375.         mov     [bit_count], 8
  376.         mov     eax, 1
  377.         shl     eax, cl
  378.         mov     [CC], eax
  379.         mov     ecx, eax
  380.         inc     eax
  381.         mov     [EOI], eax
  382.         mov     eax, gif.Null shl 16
  383.   .filltable:
  384.         stosd
  385.         inc     eax
  386.         loop    .filltable
  387.         pop     edi
  388.         mov     [img_start], edi
  389.         add     [img_end], edi
  390.         add     [row_end], edi
  391.   .reinit:
  392.         mov     edx, [EOI]
  393.         inc     edx
  394.         push    [codesize]
  395.         pop     [compsize]
  396.         call    .get_symbol
  397.         cmp     eax, [CC]
  398.         je      .reinit
  399.         call    .output
  400.   .cycle:
  401.         movzx   ebx, ax
  402.         call    .get_symbol
  403.         cmp     eax, edx
  404.         jae     .notintable
  405.         cmp     eax, [CC]
  406.         je      .reinit
  407.         cmp     eax, [EOI]
  408.         je      .end
  409.         call    .output
  410.   .add:
  411.         mov     ecx, [workarea]
  412.         mov     [ecx + edx * 4], ebx
  413.         cmp     edx, 0x00000FFF
  414.         jae     .cycle
  415.         inc     edx
  416.         bsr     ebx, edx
  417.         cmp     ebx, [compsize]
  418.         jne     .noinc
  419.         inc     [compsize]
  420.   .noinc:
  421.         jmp     .cycle
  422.   .notintable:
  423.         push    eax
  424.         mov     eax, ebx
  425.         call    .output
  426.         push    ebx
  427.         movzx   eax, bx
  428.         call    .output
  429.         pop     ebx eax
  430.         jmp     .add
  431.   .end:
  432.         mov     edi, [img_end]
  433.         xor     eax, eax
  434.  
  435.   .exit:
  436.         cmp     [workarea], 0
  437.         je      @f
  438.         invoke  mem.free, [workarea]
  439.     @@: xor     eax, eax
  440.         ret
  441.  
  442.   .error:
  443.         cmp     [workarea], 0
  444.         je      @f
  445.         invoke  mem.free, [workarea]
  446.     @@: xor     eax, eax
  447.         inc     eax
  448.         ret
  449.  
  450. ;;------------------------------------------------------------------------------------------------;;
  451.  
  452. img.decode.gif._.process_image.get_symbol:
  453.         mov     ecx, [compsize]
  454.         push    ecx
  455.         xor     eax, eax
  456.  
  457.   .shift:
  458.         ror     byte[esi], 1
  459.         rcr     eax,1
  460.         dec     [bit_count]
  461.         jnz     .loop1
  462.         inc     esi
  463.         cmp     esi, [block_ofs]
  464.         jb      .noblock
  465.         push    eax
  466.         xor     eax, eax
  467.         lodsb
  468.         test    eax, eax
  469.         jnz     .nextbl
  470.         mov     eax, [EOI]
  471.         sub     esi, 2
  472.         add     esp, 8
  473.         jmp     .exit
  474.  
  475.   .nextbl:
  476.         add     eax, esi
  477.         mov     [block_ofs], eax
  478.         pop     eax
  479.  
  480.   .noblock:
  481.         mov     [bit_count], 8
  482.  
  483.   .loop1:
  484.         loop    .shift
  485.         pop     ecx
  486.         rol     eax, cl
  487.  
  488.   .exit:
  489.         xor     ecx, ecx
  490.         retn
  491.  
  492. ;;------------------------------------------------------------------------------------------------;;
  493.  
  494. img.decode.gif._.process_image.output:
  495.         push    esi eax edx
  496.         mov     edx, [workarea]
  497.  
  498.   .next:
  499.         pushw   [edx + eax * 4]
  500.         mov     ax, [edx + eax * 4 + 2]
  501.         inc     ecx
  502.         cmp     ax, gif.Null
  503.         jnz     .next
  504.         shl     ebx, 16
  505.         mov     bx, [esp]
  506.  
  507.   .loop2:
  508.         pop     ax
  509.         stosb
  510.  
  511.         cmp     edi, [row_end]
  512.         jb      .norowend
  513.         mov     eax, [width]
  514.         push    eax
  515.         sub     edi, eax
  516.         add     eax, eax
  517.         cmp     [pass], 3
  518.         je      @f
  519.         add     eax, eax
  520.         cmp     [pass], 2
  521.         je      @f
  522.         add     eax, eax
  523.     @@: add     edi, eax
  524.         pop     eax
  525.         cmp     edi, [img_end]
  526.         jb      .nextrow
  527.         mov     edi, [img_start]
  528.         inc     [pass]
  529.         add     edi, eax
  530.         cmp     [pass], 3
  531.         je      @f
  532.         add     edi, eax
  533.         cmp     [pass], 2
  534.         je      @f
  535.         add     edi, eax
  536.         add     edi, eax
  537.     @@:
  538.  
  539.   .nextrow:
  540.         add     eax, edi
  541.         mov     [row_end], eax
  542.         xor     eax, eax
  543.  
  544.   .norowend:
  545.         loop    .loop2
  546.         pop     edx eax esi
  547.         retn
  548.  
  549. endp
  550.  
  551.  
  552. ;;================================================================================================;;
  553. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  554. ;;================================================================================================;;
  555. ;! Below is private data you should never use directly from your code                             ;;
  556. ;;================================================================================================;;
  557. ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
  558. ;;================================================================================================;;
  559.  
  560.  
  561. ;
  562.