Subversion Repositories Kolibri OS

Rev

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

  1. ; GIF LITE v3.0 by Willow
  2. ; Written in pure assembler by Ivushkin Andrey aka Willow
  3. ; Modified by Diamond
  4. ;
  5. ; This include file will contain functions to handle GIF image format
  6. ;
  7. ; Created: August 15, 2004
  8. ; Last changed: June 24, 2007
  9.  
  10. ; Requires kglobals.inc (iglobal/uglobal macro)
  11. ; (program must 'include "kglobals.inc"' and say 'IncludeUGlobal'
  12. ; somewhere in uninitialized data area).
  13.  
  14. ; Configuration: [changed from program which includes this file]
  15. ; 1. The constant COLOR_ORDER: must be one of
  16. ;    PALETTE - for 8-bit image with palette (sysfunction 65)
  17. ;    MENUETOS - for MenuetOS and KolibriOS color order (sysfunction 7)
  18. ;    OTHER - for standard color order
  19. ; 2. Define constant GIF_SUPPORT_INTERLACED if you want to support interlaced
  20. ;    GIFs.
  21. ; 3. Single image mode vs multiple image mode:
  22. ;    if the program defines the variable 'gif_img_count' of type dword
  23. ;    somewhere, ReadGIF will enter multiple image mode: gif_img_count
  24. ;    will be initialized with image count, output format is GIF_list,
  25. ;    the function GetGIFinfo retrieves Nth image info. Otherwise, ReadGIF
  26. ;    uses single image mode: exit after end of first image, output is
  27. ;    <dd width,height, times width*height[*3] db image>
  28.  
  29. if ~ (COLOR_ORDER in <PALETTE,MENUETOS,OTHER>)
  30. ; This message may not appear under MenuetOS, so watch...
  31.   display 'Please define COLOR_ORDER: PALETTE, MENUETOS or OTHER',13,10
  32. end if
  33.  
  34. if defined gif_img_count
  35. ; virtual structure, used internally
  36.  
  37. struct GIF_list
  38.     NextImg rd 1
  39.     Left   rw 1
  40.     Top    rw 1
  41.     Width  rw 1
  42.     Height rw 1
  43.     Delay  rd 1
  44.     Displacement rd 1 ; 0 = not specified
  45.                        ; 1 = do not dispose
  46.                        ; 2 = restore to background color
  47.                        ; 3 = restore to previous
  48. if COLOR_ORDER eq PALETTE
  49.     Image rd 1
  50. end if
  51. ends
  52.  
  53. struct GIF_info
  54.     Left   rw 1
  55.     Top    rw 1
  56.     Width  rw 1
  57.     Height rw 1
  58.     Delay  rd 1
  59.     Displacement rd 1
  60. if COLOR_ORDER eq PALETTE
  61.     Palette rd 1
  62. end if
  63. ends
  64.  
  65. ; ****************************************
  66. ;   FUNCTION GetGIFinfo - retrieve Nth image info
  67. ; ****************************************
  68. ; in:
  69. ;   esi - pointer to image list header
  70. ;   ecx - image_index (0...img_count-1)
  71. ;   edi - pointer to GIF_info structure to be filled
  72.  
  73. ; out:
  74. ;   eax - pointer to RAW data, or 0, if error
  75.  
  76. GetGIFinfo:
  77.     push  esi ecx edi
  78.     xor   eax,eax
  79.     jecxz .eloop
  80.   .lp:
  81.     mov   esi,[esi]
  82.     test  esi,esi
  83.     jz    .error
  84.     loop  .lp
  85.   .eloop:
  86.     lodsd
  87.     movsd
  88.     movsd
  89.     movsd
  90.     movsd
  91. if COLOR_ORDER eq PALETTE
  92.     lodsd
  93.     mov   [edi],esi
  94. else
  95.     mov   eax,esi
  96. end if
  97.   .error:
  98.     pop   edi ecx esi
  99.     ret
  100.  
  101. end if
  102.  
  103. _null fix 0x1000
  104.  
  105. ; ****************************************
  106. ;   FUNCTION ReadGIF - unpacks GIF image
  107. ; ****************************************
  108. ; in:
  109. ;   esi - pointer to GIF file in memory
  110. ;   edi - pointer to output image list
  111.  
  112. ; out:
  113. ;   eax - 0, all OK;
  114. ;   eax - 1, invalid signature;
  115. ;   eax >=8, unsupported image attributes
  116. ;
  117.  
  118. ReadGIF:
  119.     push esi edi
  120.     mov  [.cur_info],edi
  121.     xor  eax,eax
  122.     mov  [.globalColor],eax
  123. if defined gif_img_count
  124.     mov  [gif_img_count],eax
  125.     mov  [.anim_delay],eax
  126.     mov  [.anim_disp],eax
  127. end if
  128.     inc  eax
  129.     cmp  dword[esi],'GIF8'
  130.     jne  .ex            ; signature
  131.     mov  ecx,[esi+0xa]
  132.     add  esi,0xd
  133.     mov  edi,esi
  134.     test cl,cl
  135.     jns  .nextblock
  136.     mov  [.globalColor],esi
  137.     call .Gif_skipmap
  138.   .nextblock:
  139.     cmp  byte[edi],0x21
  140.     jne  .noextblock
  141.     inc  edi
  142. if defined gif_img_count
  143.     cmp  byte[edi],0xf9 ; Graphic Control Ext
  144.     jne  .no_gc
  145.     movzx eax,word [edi+3]
  146.     mov  [.anim_delay],eax
  147.     mov  al,[edi+2]
  148.     shr  al,2
  149.     and  eax,7
  150.     mov  [.anim_disp],eax
  151.     add  edi,7
  152.     jmp  .nextblock
  153.   .no_gc:
  154. end if
  155.     inc  edi
  156.   .block_skip:
  157.     movzx eax,byte[edi]
  158.     lea  edi,[edi+eax+1]
  159.     test eax,eax
  160.     jnz  .block_skip
  161.     jmp  .nextblock
  162.   .noextblock:
  163.     mov  al,8
  164.     cmp  byte[edi],0x2c    ; image beginning
  165.     jne  .ex
  166. if defined gif_img_count
  167.     inc  [gif_img_count]
  168. end if
  169.     inc  edi
  170.     mov  esi,[.cur_info]
  171. if defined gif_img_count
  172.     add  esi,4
  173. end if
  174.     xchg esi,edi
  175. if defined GIF_SUPPORT_INTERLACED
  176.     movzx ecx,word[esi+4]
  177.     mov  [.width],ecx
  178.     movzx eax,word[esi+6]
  179.     imul eax,ecx
  180. if ~(COLOR_ORDER eq PALETTE)
  181.     lea  eax,[eax*3]
  182. end if
  183.     mov  [.img_end],eax
  184.     inc  eax
  185.     mov  [.row_end],eax
  186.     and  [.pass],0
  187.     test byte[esi+8],40h
  188.     jz   @f
  189. if ~(COLOR_ORDER eq PALETTE)
  190.     lea  ecx,[ecx*3]
  191. end if
  192.     mov  [.row_end],ecx
  193. @@:
  194. end if
  195. if defined gif_img_count
  196.     movsd
  197.     movsd
  198.     mov  eax,[.anim_delay]
  199.     stosd
  200.     mov  eax,[.anim_disp]
  201.     stosd
  202. else
  203.     movzx eax,word[esi+4]
  204.     stosd
  205.     movzx eax,word[esi+6]
  206.     stosd
  207.     add   esi,8
  208. end if
  209.     push edi
  210.     mov  ecx,[esi]
  211.     inc  esi
  212.     test cl,cl
  213.     js   .uselocal
  214.     push [.globalColor]
  215.     mov  edi,esi
  216.     jmp  .setPal
  217.   .uselocal:
  218.     call .Gif_skipmap
  219.     push esi
  220.   .setPal:
  221.     movzx ecx,byte[edi]
  222.     inc  ecx
  223.     mov  [.codesize],ecx
  224.     dec  ecx
  225. if ~(COLOR_ORDER eq PALETTE)
  226.     pop  [.Palette]
  227. end if
  228.     lea  esi,[edi+1]
  229.     mov  edi,.gif_workarea
  230.     xor  eax,eax
  231.     lodsb               ; eax - block_count
  232.     add  eax,esi
  233.     mov  [.block_ofs],eax
  234.     mov  [.bit_count],8
  235.     mov  eax,1
  236.     shl  eax,cl
  237.     mov  [.CC],eax
  238.     mov  ecx,eax
  239.     inc  eax
  240.     mov  [.EOI],eax
  241.     mov  eax, _null shl 16
  242.   .filltable:
  243.     stosd
  244.     inc  eax
  245.     loop .filltable
  246. if COLOR_ORDER eq PALETTE
  247.     pop  eax
  248.     pop  edi
  249.     push edi
  250.     scasd
  251.     push esi
  252.     mov  esi,eax
  253.     mov  ecx,[.CC]
  254. @@:
  255.     lodsd
  256.     dec  esi
  257.     bswap eax
  258.     shr  eax,8
  259.     stosd
  260.     loop @b
  261.     pop  esi
  262.     pop  eax
  263.     mov  [eax],edi
  264. else
  265.     pop  edi
  266. end if
  267. if defined GIF_SUPPORT_INTERLACED
  268.     mov  [.img_start],edi
  269.     add  [.img_end],edi
  270.     add  [.row_end],edi
  271. end if
  272.   .reinit:
  273.     mov  edx,[.EOI]
  274.     inc  edx
  275.     push [.codesize]
  276.     pop  [.compsize]
  277.     call .Gif_get_sym
  278.     cmp  eax,[.CC]
  279.     je   .reinit
  280.     call .Gif_output
  281.   .cycle:
  282.     movzx ebx,ax
  283.     call .Gif_get_sym
  284.     cmp  eax,edx
  285.     jae  .notintable
  286.     cmp  eax,[.CC]
  287.     je   .reinit
  288.     cmp  eax,[.EOI]
  289.     je   .end
  290.     call .Gif_output
  291.   .add:
  292.     mov  dword [.gif_workarea+edx*4],ebx
  293.     cmp  edx,0xFFF
  294.     jae  .cycle
  295.     inc  edx
  296.     bsr  ebx,edx
  297.     cmp  ebx,[.compsize]
  298.     jne  .noinc
  299.     inc  [.compsize]
  300.   .noinc:
  301.     jmp  .cycle
  302.   .notintable:
  303.     push eax
  304.     mov  eax,ebx
  305.     call .Gif_output
  306.     push ebx
  307.     movzx eax,bx
  308.     call .Gif_output
  309.     pop  ebx eax
  310.     jmp  .add
  311.   .end:
  312. if defined GIF_SUPPORT_INTERLACED
  313.     mov  edi,[.img_end]
  314. end if
  315. if defined gif_img_count
  316.     mov  eax,[.cur_info]
  317.     mov  [eax],edi
  318.     mov  [.cur_info],edi
  319.     add  esi,2
  320.     xchg esi,edi
  321.   .nxt:
  322.     cmp  byte[edi],0
  323.     jnz  .continue
  324.     inc  edi
  325.     jmp  .nxt
  326.   .continue:
  327.     cmp  byte[edi],0x3b
  328.     jne  .nextblock
  329.     xchg esi,edi
  330.     and  dword [eax],0
  331. end if
  332.     xor  eax,eax
  333.   .ex:
  334.     pop  edi esi
  335.     ret
  336.  
  337. .Gif_skipmap:
  338. ; in: ecx - image descriptor, esi - pointer to colormap
  339. ; out: edi - pointer to area after colormap
  340.  
  341.     and  ecx,111b
  342.     inc  ecx            ; color map size
  343.     mov  ebx,1
  344.     shl  ebx,cl
  345.     lea  ebx,[ebx*2+ebx]
  346.     lea  edi,[esi+ebx]
  347.     ret
  348.  
  349. .Gif_get_sym:
  350.     mov  ecx,[.compsize]
  351.     push ecx
  352.     xor  eax,eax
  353.   .shift:
  354.     ror  byte[esi],1
  355.     rcr  eax,1
  356.     dec  [.bit_count]
  357.     jnz  .loop1
  358.     inc  esi
  359.     cmp  esi,[.block_ofs]
  360.     jb   .noblock
  361.     push eax
  362.     xor  eax,eax
  363.     lodsb
  364.     test eax,eax
  365.     jnz  .nextbl
  366.     mov  eax,[.EOI]
  367.     sub  esi,2
  368.     add  esp,8
  369.     jmp  .exx
  370.   .nextbl:
  371.     add  eax,esi
  372.     mov  [.block_ofs],eax
  373.     pop  eax
  374.   .noblock:
  375.     mov  [.bit_count],8
  376.   .loop1:
  377.     loop .shift
  378.     pop  ecx
  379.     rol  eax,cl
  380.   .exx:
  381.     xor  ecx,ecx
  382.     ret
  383.  
  384. .Gif_output:
  385.     push esi eax edx
  386.     mov  edx,.gif_workarea
  387.   .next:
  388.     push word[edx+eax*4]
  389.     mov  ax,word[edx+eax*4+2]
  390.     inc  ecx
  391.     cmp  ax,_null
  392.     jnz  .next
  393.     shl  ebx,16
  394.     mov  bx,[esp]
  395.   .loop2:
  396.     pop  ax
  397.  
  398.     if COLOR_ORDER eq PALETTE
  399.         stosb
  400.     else
  401.         lea  esi,[eax+eax*2]
  402.         add  esi,[.Palette]
  403.  
  404.     if COLOR_ORDER eq MENUETOS
  405.         mov  esi,[esi]
  406.         bswap esi
  407.         shr  esi,8
  408.         mov  [edi],esi
  409.         add  edi,3
  410.     else
  411.         movsb
  412.         movsb
  413.         movsb
  414.     end if
  415.     end if
  416.  
  417. if defined GIF_SUPPORT_INTERLACED
  418.     cmp  edi,[.row_end]
  419.     jb   .norowend
  420.     mov  eax,[.width]
  421. if ~(COLOR_ORDER eq PALETTE)
  422.     lea  eax,[eax*3]
  423. end if
  424.     push eax
  425.     sub  edi,eax
  426.     add  eax,eax
  427.     cmp  [.pass],3
  428.     jz   @f
  429.     add  eax,eax
  430.     cmp  [.pass],2
  431.     jz   @f
  432.     add  eax,eax
  433. @@:
  434.     add  edi,eax
  435.     pop  eax
  436.     cmp  edi,[.img_end]
  437.     jb   .nextrow
  438.     mov  edi,[.img_start]
  439.     inc  [.pass]
  440.     add  edi,eax
  441.     cmp  [.pass],3
  442.     jz   @f
  443.     add  edi,eax
  444.     cmp  [.pass],2
  445.     jz   @f
  446.     add  edi,eax
  447.     add  edi,eax
  448. @@:
  449. .nextrow:
  450.     add  eax,edi
  451.     mov  [.row_end],eax
  452.     xor  eax,eax
  453. .norowend:
  454. end if
  455.  
  456.     loop .loop2
  457.     pop  edx eax esi
  458.     ret
  459.  
  460. uglobal
  461. align 4
  462.     ReadGIF.globalColor rd 1
  463.     ReadGIF.cur_info rd 1        ; image table pointer
  464.     ReadGIF.codesize rd 1
  465.     ReadGIF.compsize rd 1
  466.     ReadGIF.bit_count rd 1
  467.     ReadGIF.CC rd 1
  468.     ReadGIF.EOI rd 1
  469. if ~(COLOR_ORDER eq PALETTE)
  470.     ReadGIF.Palette rd 1
  471. end if
  472.     ReadGIF.block_ofs rd 1
  473. if defined GIF_SUPPORT_INTERLACED
  474.     ReadGIF.row_end rd 1
  475.     ReadGIF.img_end rd 1
  476.     ReadGIF.img_start rd 1
  477.     ReadGIF.pass rd 1
  478.     ReadGIF.width rd 1
  479. end if
  480. if defined gif_img_count
  481.     ReadGIF.anim_delay rd 1
  482.     ReadGIF.anim_disp rd 1
  483. end if
  484.     ReadGIF.gif_workarea rb 16*1024
  485. endg
  486.