gif.c
上传用户:hengzhunsh
上传日期:2013-09-07
资源大小:19k
文件大小:6k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*
  2.     fbv  --  simple image viewer for the linux framebuffer
  3.     Copyright (C) 2000, 2001, 2003  Mateusz Golicz
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #ifdef FBV_SUPPORT_GIF
  18. #include "fbv.h"
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <setjmp.h>
  24. #include <gif_lib.h>
  25. #include <signal.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #define min(a,b) ((a) < (b) ? (a) : (b))
  30. #define gflush return(FH_ERROR_FILE);
  31. #define grflush { DGifCloseFile(gft); return(FH_ERROR_FORMAT); }
  32. #define mgrflush { free(lb); free(slb); DGifCloseFile(gft); return(FH_ERROR_FORMAT); }
  33. #define agflush return(FH_ERROR_FORMAT);
  34. #define agrflush { DGifCloseFile(gft); return(FH_ERROR_FORMAT); }
  35. int fh_gif_id(char *name)
  36. {
  37.     int fd;
  38.     char id[4];
  39.     fd=open(name,O_RDONLY); if(fd==-1) return(0);
  40.     read(fd,id,4);
  41.     close(fd);
  42.     if(id[0]=='G' && id[1]=='I' && id[2]=='F') return(1);
  43.     return(0);
  44. }
  45. inline void m_rend_gif_decodecolormap(unsigned char *cmb,unsigned char *rgbb,ColorMapObject *cm,int s,int l, int transparency)
  46. {
  47.     GifColorType *cmentry;
  48.     int i;
  49.     for(i=0;i<l;i++)
  50.     {
  51. cmentry=&cm->Colors[cmb[i]];
  52. *(rgbb++)=cmentry->Red;
  53. *(rgbb++)=cmentry->Green;
  54. *(rgbb++)=cmentry->Blue;
  55.     }
  56. }
  57. /* Thanks goes here to Mauro Meneghin, who implemented interlaced GIF files support */
  58. int fh_gif_load(char *name,unsigned char *buffer, unsigned char ** alpha, int x,int y)
  59. {
  60.   int in_nextrow[4]={8,8,4,2};   //interlaced jump to the row current+in_nextrow
  61.   int in_beginrow[4]={0,4,2,1};  //begin pass j from that row number
  62.   int transparency=-1;  //-1 means not transparency present
  63.     int px,py,i,ibxs;
  64.     int j;
  65.     char *fbptr;
  66.     char *lb;
  67.     char *slb;
  68.     GifFileType *gft;
  69.     GifByteType *extension;
  70.     int extcode;
  71.     GifRecordType rt;
  72.     ColorMapObject *cmap;
  73.     int cmaps;
  74.     gft=DGifOpenFileName(name);
  75.     if(gft==NULL){printf("err5n"); gflush;} //////////
  76.     do
  77.     {
  78. if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
  79. switch(rt)
  80. {
  81.     case IMAGE_DESC_RECORD_TYPE:
  82. if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
  83. px=gft->Image.Width;
  84. py=gft->Image.Height;
  85. lb=(char*)malloc(px*3);
  86. slb=(char*) malloc(px);
  87. //  printf("reading...n");
  88. if(lb!=NULL && slb!=NULL)
  89. {
  90. unsigned char *alphaptr = NULL;
  91.     cmap=(gft->Image.ColorMap ? gft->Image.ColorMap : gft->SColorMap);
  92.     cmaps=cmap->ColorCount;
  93.     ibxs=ibxs*3;
  94.     fbptr=(char*)buffer;
  95. if(transparency != -1)
  96. {
  97. alphaptr = malloc(px * py);
  98. *alpha = alphaptr;
  99. }
  100.     if(!(gft->Image.Interlace))
  101.     {
  102. for(i=0;i<py;i++,fbptr+=px*3)
  103. {
  104. int j;
  105.     if(DGifGetLine(gft,(GifPixelType*)slb,px)==GIF_ERROR) mgrflush;
  106.     m_rend_gif_decodecolormap((unsigned char*)slb,(unsigned char*)lb,cmap,cmaps,px,transparency);
  107.     memcpy(fbptr,lb,px*3);
  108. if(alphaptr)
  109. for(j = 0; j<px; j++) *(alphaptr++) = (((unsigned char*) slb)[j] == transparency) ? 0x00 : 0xff;
  110.          }
  111.                     }
  112.                     else
  113.     {
  114. unsigned char * aptr = NULL;
  115.                for(j=0;j<4;j++)
  116.                {
  117. int k;
  118.         if(alphaptr)
  119. aptr = alphaptr + (in_beginrow[j] * px);
  120.     fbptr=(char*)buffer + (in_beginrow[j] * px * 3);
  121.     for(i = in_beginrow[j]; i<py; i += in_nextrow[j], fbptr += px * 3 * in_nextrow[j], aptr += px * in_nextrow[j])
  122.     {
  123. if(DGifGetLine(gft,(GifPixelType*)slb,px)==GIF_ERROR) mgrflush; /////////////
  124. m_rend_gif_decodecolormap((unsigned char*)slb,(unsigned char*)lb,cmap,cmaps,px,transparency);
  125. memcpy(fbptr,lb,px*3);
  126. if(alphaptr)
  127. for(k = 0; k<px; k++) aptr[k] = (((unsigned char*) slb)[k] == transparency) ? 0x00 : 0xff;
  128.                }
  129. }
  130.     }
  131. }
  132. if(lb) free(lb);
  133. if(slb) free(slb);
  134.                 break;
  135.     case EXTENSION_RECORD_TYPE:
  136. if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR) grflush; //////////
  137. if(extcode==0xf9) //look image transparency in graph ctr extension
  138. {
  139. if(extension[1] & 1)
  140. {
  141. transparency = extension[4];
  142. }
  143. //     tran_off=(int)*extension;
  144. //     transparency=(int)*(extension+tran_off);
  145. // printf("transparency: %dn", transparency);
  146.                 }
  147. while(extension!=NULL)
  148.     if(DGifGetExtensionNext(gft,&extension) == GIF_ERROR) grflush
  149. break;
  150.     default:
  151. break;
  152. }
  153.     }
  154.     while( rt!= TERMINATE_RECORD_TYPE );
  155.     DGifCloseFile(gft);
  156.     return(FH_ERROR_OK);
  157. }
  158. int fh_gif_getsize(char *name,int *x,int *y)
  159. {
  160.     int px,py;
  161.     GifFileType *gft;
  162.     GifByteType *extension;
  163.     int extcode;
  164.     GifRecordType rt;
  165.     gft=DGifOpenFileName(name);
  166.     if(gft==NULL) gflush;
  167.     do
  168.     {
  169. if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
  170. switch(rt)
  171. {
  172.     case IMAGE_DESC_RECORD_TYPE:
  173. if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
  174. px=gft->Image.Width;
  175. py=gft->Image.Height;
  176. *x=px; *y=py;
  177. DGifCloseFile(gft);
  178. return(FH_ERROR_OK);
  179. break;
  180.     case EXTENSION_RECORD_TYPE:
  181. if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR) grflush;
  182. while(extension!=NULL)
  183.     if(DGifGetExtensionNext(gft,&extension)==GIF_ERROR) grflush;
  184. break;
  185.     default:
  186. break;
  187. }  
  188.     }
  189.     while( rt!= TERMINATE_RECORD_TYPE );
  190.     DGifCloseFile(gft);
  191.     return(FH_ERROR_FORMAT);
  192. }
  193. #endif