Subversion Repositories Kolibri OS

Rev

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