www.pudn.com > Cimage.zip > IMAGIF.CPP
/* * File: imagif.cc * Purpose: Platform Independent GIF Image Class * Author: Alejandro Aguilar Sierra * Created: 1995 * Copyright: (c) 1995, Alejandro Aguilar Sierra* */ // #include "stdafx.h" #include "imagif.h" #if CIMAGE_SUPPORT_GIF #include "imaiter.h" #include "gifdecod.h" #include // Force byte alignment (Borland) #if defined __BORLANDC__ #pragma option -a1 #elif defined _MSV_VER #pragma option /Zp1 #endif //#include //static ofstream log("x.log"); #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ////////////////////////// AD - for interlace /////////////////////////////// int interlaced, iypos, istep, iheight, ipass; ///////////////////////////////////////////////////////////////////////////// #define GIFBUFTAM 16384 struct rgb { byte r,g,b; }; ////////////////////////// AD - for transparency /////////////////////////////// static struct { byte transpcolflag:1; byte userinputflag:1; byte dispmeth:3; byte res:3; byte delaytimehi; byte delaytimelo; byte transpcolindex; } gifgce; static struct { /* Logic Screen Descriptor */ char header[6]; /* Firma and version */ USHORT scrwidth; USHORT scrheight; char pflds; char bcindx; char pxasrat; } dscgif; static struct { /* Image Descriptor */ USHORT l; USHORT t; USHORT w; USHORT h; byte pf; } image; static struct { /* Tabla de colores */ SHORT colres; /* color resolution */ SHORT sogct; /* size of global color table */ rgb paleta[256]; /* paleta */ } TabCol; static CImageIterator* iter; static FILE *f; static int ibf = GIFBUFTAM+1; static byte buf[GIFBUFTAM]; int out_line(unsigned char *pixels, int linelen); BOOL CImageGIF::ReadFile(const CString& imageFileName) { if (imageFileName != "") filename = imageFileName; // puts("Empezando... "); if ((f = fopen((const char *)filename, "rb"))==NULL) { // printf("no se pudo abrir!"); return FALSE; } fread((char*)&dscgif,/*sizeof(dscgif)*/13,1,f); //if (strncmp(dscgif.header,"GIF8",3)!=0) { if (strncmp(dscgif.header,"GIF8",4)!=0) { // puts("no es la firma!"); return FALSE; } ////////////////////////// AD - for interlace /////////////////////////////// //TabCol.sogct = 1<<((dscgif.pflds & 0x0007) + 0x0001); //TabCol.colres = (dscgif.pflds>>6) & 7 + 1; TabCol.sogct = 1 << (dscgif.pflds & 0x07)+1; TabCol.colres = ((int)(dscgif.pflds & 0x70) >> 3) + 1; // Global colour map? if (dscgif.pflds & 0x80) { fread((char*)TabCol.paleta,/*sizeof(struct rgb)*/3*TabCol.sogct,1,f); //log << "Global colour map" << endl; } char ch; loop: if (fread(&ch, 1, 1, f) <= 0) goto done; if (ch == '!') // extension { unsigned char count; unsigned char fc; //log << "EXTENSION: "; if (fread(&fc, 1, 1, f) <= 0) // function-code goto done; //log << hex << (int)fc << dec << endl; //////////////// AD - for transparency ////////////////////////// if (fc == 0xF9) { //log << "Transparent" << endl; if (fread(&count, 1, 1, f) <= 0) goto done; if (fread(&gifgce, 1, /*sizeof(gifgce)*/4, f) != count) goto done; if (gifgce.transpcolflag) bgindex = gifgce.transpcolindex; /////////////////////////////////////////////////////////////////// } while (fread(&count, 1, 1, f) && count) { //log << "Skipping " << count << " bytes" << endl; fseek(f, count, SEEK_CUR); } goto loop; } else if (ch == ',') // image { fread((char*)&image,/*sizeof(image)*/9,1,f); //log << "Image header" << endl; // Local colour map? if (image.pf & 0x80) { TabCol.sogct = 1 << ((image.pf & 0x07) +1); fread((char*)TabCol.paleta,/*sizeof(struct rgb)*/3*TabCol.sogct,1,f); //log << "Local colour map" << endl; } Create(image.w, image.h, 8); if ((image.pf & 0x80) || (dscgif.pflds & 0x80)) { unsigned char r[256], g[256], b[256]; int i, has_white = 0; for (i=0; i < TabCol.sogct; i++) { r[i] = TabCol.paleta[i].r; g[i] = TabCol.paleta[i].g; b[i] = TabCol.paleta[i].b; if (RGB(r[i],g[i],b[i]) == 0xFFFFFF) has_white = 1; } // Make transparency colour black... if (bgindex != -1) r[bgindex] = g[bgindex] = b[bgindex] = 0; // Fill in with white // AD if (bgindex != -1) { while (i < 256) { has_white = 1; r[i] = g[i] = b[i] = 255; i++; } } // Force last colour to white... // AD if ((bgindex != -1) && !has_white) r[255] = g[255] = b[255] = 255; SetPalette((bgindex != -1 ? 256 : TabCol.sogct), r, g, b); //log << "Set colour map" << endl; } iter = new CImageIterator(this); iter->Upset(); int badcode; ibf = GIFBUFTAM+1; GIFDecoder gifdec; interlaced = image.pf & 0x40; iheight = image.h; istep = 8; iypos = 0; ipass = 0; //if (interlaced) log << "Interlaced" << endl; gifdec.decoder(GetWidth(), badcode); delete iter; goto loop; } done: fclose(f); return TRUE; } int get_byte() { if (ibf>=GIFBUFTAM) { fread(buf,GIFBUFTAM,1,f); ibf = 0; } return buf[ibf++]; } int out_line(unsigned char *pixels, int linelen) { ////////////////////////// AD - for interlace /////////////////////////////// if (interlaced) { iter->SetY(iheight-iypos-1); iter->SetRow(pixels, linelen); if ((iypos += istep) >= iheight) { do { if (ipass++ > 0) istep /= 2; iypos = istep / 2; } while (iypos > iheight); } return 0; } else ///////////////////////////////////////////////////////////////////////////// if (iter->ItOK()) { iter->SetRow(pixels, linelen); (void)iter->PrevRow(); return 0; } else { // puts("chafeo"); return -1; } } #endif // CIMAGE_SUPPORT_GIF