Example #1
0
// Load image from stream
FXbool fxloadXPM(FXStream& store,FXColor*& data,FXint& width,FXint& height){
  FXchar lookuptable[1024][8],line[100],name[100],word[100],flag,best,ch;
  FXColor colortable[16384],*pix,color;
  const FXchar *src;
  FXint i,j,ncolors,cpp,c;

  // Null out
  data=NULL;
  width=0;
  height=0;
  color=0;

  // Read header line
  readline(store,name,sizeof(name));
  if(!strstr(name,"XPM")) return false;

  // Read description
  readtext(store,line,sizeof(line));

  // Parse size description
  if(__sscanf(line,"%d %d %u %u",&width,&height,&ncolors,&cpp)!=4) return false;

  // Check size
  if(width<1 || height<1 || width>16384 || height>16384) return false;

  // Sensible inputs
  if(cpp<1 || cpp>8 || ncolors<1) return false;

  // Limited number of colors for long lookup strings
  if(cpp>2 && ncolors>1024) return false;

  // Allow more colors for short lookup strings
  if(ncolors>16384) return false;

  //FXTRACE((100,"fxloadXPM: width=%d height=%d ncolors=%d cpp=%d\n",width,height,ncolors,cpp));

  // Read the color table
  for(c=0; c<ncolors; c++){
    readtext(store,line,sizeof(line));
    src=line+cpp;
    nextword(src,word);
    best='z';
    while(iskey(word)){
      flag=word[0];
      name[0]=0;
      while(nextword(src,word) && !iskey(word)){
        strncat(name,word,sizeof(name));
        }
      if(flag<best){                    // c < g < m < s
        color=fxcolorfromname(name);
        best=flag;
        }
      }
    if(cpp==1){
      colortable[(FXuchar)line[0]]=color;
      }
    else if(cpp==2){
      colortable[(((FXuchar)line[1])<<7)+(FXuchar)line[0]]=color;
      }
    else{
      colortable[c]=color;
      strncpy(lookuptable[c],line,cpp);
      }
    }

  // Try allocate pixels
  if(!allocElms(data,width*height)){
    return false;
    }

  // Read the pixels
  for(i=0,pix=data; i<height; i++){
    while(!store.eof() && (store>>ch,ch!='"')){}
    for(j=0; j<width; j++){
      store.load(line,cpp);
      if(cpp==1){
        color=colortable[(FXuchar)line[0]];
        }
      else if(cpp==2){
        color=colortable[(((FXuchar)line[1])<<7)+(FXuchar)line[0]];
        }
      else{
        for(c=0; c<ncolors; c++){
          if(strncmp(lookuptable[c],line,cpp)==0){ color=colortable[c]; break; }
          }
        }
      *pix++=color;
      }
    while(!store.eof() && (store>>ch,ch!='"')){}
    }

  // We got the image, but we're not done yet; need to read few more bytes
  // the number of bytes read here must match the number of bytes written
  // by fxsaveXPM() so that the stream won't get out of sync
  while(!store.eof()){
    store >> ch;
    if(ch=='\n') break;
    }
  return true;
  }
Example #2
0
// Load image from stream
bool fxloadGIF(FXStream& store,FXColor*& data,FXint& width,FXint& height){
  const   FXint Yinit[4]={0,4,2,1};
  const   FXint Yinc[4]={8,8,4,2};
  FXint   imwidth,imheight,interlace,ncolors,npixels,maxpixels,i;
  FXuchar c1,c2,c3,sbsize,flags,alpha,*ptr,*buf,*pix;
  FXColor colormap[256];
  FXint   BitOffset;                  // Bit Offset of next code
  FXint   ByteOffset;                 // Byte offset of next code
  FXint   XC,YC;                      // Output X and Y coords of current pixel
  FXint   Pass;                       // Used by output routine if interlaced pic
  FXint   OutCount;                   // Decompressor output 'stack count'
  FXint   CodeSize;                   // Code size, read from GIF header
  FXint   InitCodeSize;               // Starting code size, used during Clear
  FXint   Code;                       // Value returned by ReadCode
  FXint   MaxCode;                    // limiting value for current code size
  FXint   ClearCode;                  // GIF clear code
  FXint   EOFCode;                    // GIF end-of-information code
  FXint   CurCode,OldCode,InCode;     // Decompressor variables
  FXint   FirstFree;                  // First free code, generated per GIF spec
  FXint   FreeCode;                   // Decompressor,next free slot in hash table
  FXint   FinChar;                    // Decompressor variable
  FXint   BitMask;                    // AND mask for data size
  FXint   ReadMask;                   // Code AND mask for current code size
  FXint   Prefix[4096];               // The hash table used by the decompressor
  FXint   Suffix[4096];               // The hash table used by the decompressor
  FXint   OutCode[4097];              // An output array used by the decompressor

  // Null out
  data=NULL;
  width=0;
  height=0;

  // Load signature
  store >> c1;
  store >> c2;
  store >> c3;

  // Check signature
  if(c1!=TAG_SIG1 || c2!=TAG_SIG2 || c3!=TAG_SIG3) return false;

  // Load version
  store >> c1;
  store >> c2;
  store >> c3;

  // Check version
  if(c1!=TAG_VER || (c2!=TAG_OLD && c2!=TAG_NEW) || c3!=TAG_SUF) return false;

  // Get screen descriptor
  store >> c1 >> c2;    // Skip screen width
  store >> c1 >> c2;    // Skip screen height
  store >> flags;       // Get flags
  store >> alpha;       // Background
  store >> c2;          // Skip aspect ratio

  // Determine number of colors
  ncolors=2<<(flags&7);
  BitMask=ncolors-1;

  // If no colormap, spec says first 2 colors are black and white
  colormap[0]=FXRGB(0,0,0);
  colormap[1]=FXRGB(255,255,255);

  // Read global map if there is one
  if(flags&0x80){
    for(i=0; i<ncolors; i++){
      store >> ((FXuchar*)(colormap+i))[0];     // Blue
      store >> ((FXuchar*)(colormap+i))[1];     // Green
      store >> ((FXuchar*)(colormap+i))[2];     // Red
      ((FXuchar*)(colormap+i))[3]=255;          // Alpha
      }
    }

  // Process it
  while(1){
    store >> c1;
    if(c1==TAG_EXTENSION){

      // Read extension code
      store >> c2;

      // Graphic Control Extension
      if(c2==TAG_GRAPHIC){
        store >> sbsize;
        if(sbsize!=TAG_GRAPHICSIZE) return false;
        store >> flags;         // Flags
        store >> c3 >> c3;      // Delay time
        store >> alpha;         // Alpha color index; we suspect alpha<ncolors not always true...
        store >> c3;
        if(flags&1){            // Clear alpha channel of alpha color
          colormap[alpha]&=FXRGBA(255,255,255,0);       // Clear the alpha channel but keep the RGB
          }
        continue;
        }

      // Other extension
      do{
        store >> sbsize;
        store.position(store.position()+sbsize);
        }
      while(sbsize>0 && !store.eof());    // FIXME this logic still flawed
      continue;
      }