IMAGIF.CPP
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:6k
源码类别:

图片显示

开发平台:

Visual C++

  1. /*
  2.  * File: imagif.cc
  3.  * Purpose: Platform Independent GIF Image Class
  4.  * Author: Alejandro Aguilar Sierra
  5.  * Created: 1995
  6.  * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
  7.  *
  8.  */
  9. // #include "stdafx.h"
  10. #include "imagif.h"
  11. #if CIMAGE_SUPPORT_GIF
  12. #include "imaiter.h"
  13. #include "gifdecod.h"
  14. #include <stdio.h>
  15. // Force byte alignment (Borland)
  16. #if defined  __BORLANDC__
  17. #pragma option -a1
  18. #elif defined _MSV_VER
  19. #pragma option /Zp1
  20. #endif
  21. //#include <fstream.h>
  22. //static ofstream log("x.log");
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. ////////////////////////// AD - for interlace ///////////////////////////////
  29. int interlaced, iypos, istep, iheight, ipass;
  30. /////////////////////////////////////////////////////////////////////////////
  31. #define GIFBUFTAM 16384
  32. struct rgb { byte r,g,b; };
  33. ////////////////////////// AD - for transparency ///////////////////////////////
  34. static struct {
  35.   byte transpcolflag:1;
  36.   byte userinputflag:1;
  37.   byte dispmeth:3;
  38.   byte res:3;
  39.   byte delaytimehi;
  40.   byte delaytimelo;
  41.   byte transpcolindex;
  42. } gifgce;
  43. static struct {                 /* Logic Screen Descriptor  */
  44.   char header[6];        /* Firma and version */
  45.   USHORT scrwidth;
  46.   USHORT scrheight;
  47.   char pflds;
  48.   char bcindx;
  49.   char pxasrat;
  50. } dscgif;
  51. static struct {             /* Image Descriptor */
  52.   USHORT l;
  53.   USHORT t;
  54.   USHORT w;
  55.   USHORT h;
  56.   byte   pf;
  57. } image;
  58. static struct {           /*   Tabla de colores  */
  59.   SHORT colres; /* color resolution */
  60.   SHORT sogct;  /* size of global color table */
  61.   rgb paleta[256];    /*  paleta  */
  62. } TabCol;
  63. static CImageIterator* iter;
  64. static FILE *f;
  65. static  int ibf = GIFBUFTAM+1;
  66. static  byte buf[GIFBUFTAM];
  67. int out_line(unsigned char *pixels, int linelen);
  68. BOOL CImageGIF::ReadFile(const CString& imageFileName)
  69. {
  70.   if (imageFileName != "")
  71.     filename = imageFileName;
  72. //  puts("Empezando... ");
  73.   if ((f = fopen((const char *)filename, "rb"))==NULL) {
  74.  // printf("no se pudo abrir!");
  75. return FALSE;
  76.   }
  77. fread((char*)&dscgif,/*sizeof(dscgif)*/13,1,f);
  78.  //if (strncmp(dscgif.header,"GIF8",3)!=0) {
  79.  if (strncmp(dscgif.header,"GIF8",4)!=0) {
  80. // puts("no es la firma!");
  81. return FALSE;
  82.  }
  83. ////////////////////////// AD - for interlace ///////////////////////////////
  84.  //TabCol.sogct = 1<<((dscgif.pflds & 0x0007) + 0x0001);
  85.  //TabCol.colres = (dscgif.pflds>>6) & 7 + 1;
  86.  TabCol.sogct = 1 << (dscgif.pflds & 0x07)+1;
  87.  TabCol.colres = ((int)(dscgif.pflds & 0x70) >> 3) + 1;
  88.  // Global colour map?
  89.  if (dscgif.pflds & 0x80)
  90.  {
  91. fread((char*)TabCol.paleta,/*sizeof(struct rgb)*/3*TabCol.sogct,1,f);
  92. //log << "Global colour map" << endl;
  93.  }
  94.  char ch;
  95. loop:
  96.  if (fread(&ch, 1, 1, f) <= 0)
  97. goto done;
  98.  if (ch == '!')                     // extension
  99.  {
  100. unsigned char count;
  101. unsigned char fc;
  102. //log << "EXTENSION: ";
  103. if (fread(&fc, 1, 1, f) <= 0)   // function-code
  104. goto done;
  105. //log << hex << (int)fc << dec << endl;
  106. //////////////// AD - for transparency //////////////////////////
  107. if (fc == 0xF9)
  108. {
  109. //log << "Transparent" << endl;
  110. if (fread(&count, 1, 1, f) <= 0)
  111. goto done;
  112. if (fread(&gifgce, 1, /*sizeof(gifgce)*/4, f) != count)
  113. goto done;
  114. if (gifgce.transpcolflag)
  115. bgindex = gifgce.transpcolindex;
  116. ///////////////////////////////////////////////////////////////////
  117. }
  118. while (fread(&count, 1, 1, f) && count)
  119. {
  120. //log << "Skipping " << count << " bytes" << endl;
  121. fseek(f, count, SEEK_CUR);
  122. }
  123. goto loop;
  124.  }
  125.  else if (ch == ',')                 // image
  126.  {
  127. fread((char*)&image,/*sizeof(image)*/9,1,f);
  128. //log << "Image header" << endl;
  129. // Local colour map?
  130. if (image.pf & 0x80)
  131. {
  132. TabCol.sogct = 1 << ((image.pf & 0x07) +1);
  133. fread((char*)TabCol.paleta,/*sizeof(struct rgb)*/3*TabCol.sogct,1,f);
  134. //log << "Local colour map" << endl;
  135. }
  136. Create(image.w, image.h, 8);
  137. if ((image.pf & 0x80) || (dscgif.pflds & 0x80))
  138. {
  139. unsigned char r[256], g[256], b[256];
  140. int i, has_white = 0;
  141. for (i=0; i < TabCol.sogct; i++)
  142. {
  143. r[i] = TabCol.paleta[i].r;
  144. g[i] = TabCol.paleta[i].g;
  145. b[i] = TabCol.paleta[i].b;
  146. if (RGB(r[i],g[i],b[i]) == 0xFFFFFF)
  147. has_white = 1;
  148. }
  149. // Make transparency colour black...
  150. if (bgindex != -1)
  151. r[bgindex] = g[bgindex] = b[bgindex] = 0;
  152. // Fill in with white // AD
  153. if (bgindex != -1)
  154. {
  155. while (i < 256)
  156. {
  157. has_white = 1;
  158. r[i] = g[i] = b[i] = 255;
  159. i++;
  160. }
  161. }
  162. // Force last colour to white...   // AD
  163. if ((bgindex != -1) && !has_white)
  164. r[255] = g[255] = b[255] = 255;
  165. SetPalette((bgindex != -1 ? 256 : TabCol.sogct), r, g, b);
  166. //log << "Set colour map" << endl;
  167. }
  168. iter = new CImageIterator(this);
  169. iter->Upset();
  170. int badcode;
  171. ibf = GIFBUFTAM+1;
  172. GIFDecoder gifdec;
  173. interlaced = image.pf & 0x40;
  174. iheight = image.h;
  175. istep = 8;
  176. iypos = 0;
  177. ipass = 0;
  178. //if (interlaced) log << "Interlaced" << endl;
  179. gifdec.decoder(GetWidth(), badcode);
  180. delete iter;
  181. goto loop;
  182.  }
  183. done:
  184.  fclose(f);
  185.   return TRUE;
  186. }
  187. int get_byte()
  188. {
  189.   if (ibf>=GIFBUFTAM) {
  190.  fread(buf,GIFBUFTAM,1,f);
  191.  ibf = 0;
  192.   }
  193.   return buf[ibf++];
  194. }
  195. int out_line(unsigned char *pixels, int linelen)
  196. {
  197. ////////////////////////// AD - for interlace ///////////////////////////////
  198.   if (interlaced)
  199.   {
  200.  iter->SetY(iheight-iypos-1);
  201.  iter->SetRow(pixels, linelen);
  202.  if ((iypos += istep) >= iheight)
  203.  {
  204. do
  205. {
  206. if (ipass++ > 0)
  207. istep /= 2;
  208. iypos = istep / 2;
  209. }
  210.   while (iypos > iheight);
  211.  }
  212.  return 0;
  213.   }
  214.   else
  215. /////////////////////////////////////////////////////////////////////////////
  216.   if (iter->ItOK()) {
  217.  iter->SetRow(pixels, linelen);
  218.  (void)iter->PrevRow();
  219.  return 0;
  220.   }
  221.   else {
  222. //  puts("chafeo");
  223.  return -1;
  224.   }
  225. }
  226. #endif  //  CIMAGE_SUPPORT_GIF