#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define LWORD unsigned long
#define WORD  unsigned short
#define BYTE  unsigned char

// GIF-parameter
unsigned char SuffixTable[4999], ByteBuf[2592], BlockBuf[256];
short EncodeTable[4999], PrefixTable[4999];      // have in common_use
LWORD TempCode;
short Code, RunBits, ByteCount, ShiftBits;

#define n1  4096
#define n2  4032
#define n11 512
#define n22 504
char head[72][80],a[30];
unsigned char b[n11*n22];
FILE  *fp,*fp1;
float d[n2][n1];
main(ac,av)
int ac; char *av[];
{
  int   i,j,k,i1,j1,ip=0,q;
  float x,y;
  if(ac<2){
    printf("\n\t ****** shrink fit for look ********\n");
    printf("\n\tUsage: b4 !\n\n");
    exit(0);
  }
  system("ls p*.fit >1.1");
//  system("dir/b p*.fit >1.1");
  fp1=fopen("1.1","r");
l10:
  fgets(a,30,fp1);  if(feof(fp1))goto l20;
  a[strlen(a)-1]=0;
  fp=fopen(a,"rb");
  fread(head,72,80,fp);
  fread(d,n1*n2,4,fp); fclose(fp); swap4(d,n1*n2*4);
  printf("%3d: %s --> ",++ip,a);
  sscanf(&head[32][12],"%f",&y);
  k=0;
  for(j=0;j<n2;j+=8)for(i=0;i<n1;i+=8){
    x=0.;
    for(j1=j;j1<j+8;j1++)for(i1=i;i1<i+8;i1++)x+=d[j1][i1]-y;
    x/=64.;  x+=50.;  if(x<0.)x=0.; if(x>255.)x=255.;
    q=x;
    b[k++]=q;
  }
  head[1][27]=head[1][28]=32; head[1][29]=56;
  head[3][26]=32; head[3][27]='5'; head[3][28]='1'; head[3][29]='2';
  head[4][26]=32; head[4][27]='5'; head[4][28]='0'; head[4][29]='4';
  sprintf(&head[35][0],"END"); for(i=3;i<80;i++)head[35][i]=32;
  a[0]='b'; k=strlen(a); a[k-3]='g'; a[k-1]='f'; printf("%s\n",a);
  fp=fopen(a,"wb");
  togif(b,n11,n22);
  fclose(fp);   goto l10;
l20:
  fclose(fp1);
}

swap4(a,n)
char *a; int n;
{
  int i;  char c;
  for(i=0;i<n;i+=4){
    c=a[i]; a[i]=a[i+3]; a[i+3]=c;
    c=a[i+1]; a[i+1]=a[i+2]; a[i+2]=c;
  }
}

FillBlockBuf()
{
  TempCode |= (unsigned int)Code << ShiftBits;
  ShiftBits += RunBits;
  while(ShiftBits >= 8)  {
    BlockBuf[++ByteCount] = TempCode & 0x00FF;
    if(ByteCount == 255){
      BlockBuf[0] = (unsigned char)ByteCount;
      fwrite(BlockBuf, 1, ByteCount+1, fp);
      ByteCount = 0;
    }
    TempCode >>= 8;
    ShiftBits -= 8;
  }
}

togif(c256,m1,m2)
unsigned char *c256;
int m1,m2;
{
short Encode, MaxCodeSize, Width, Height, Dots, Rows;
short PrefixCode, SuffixCode, RandomIndex, Val;
short head1[7]={0x4947,0x3846,0x6137,0,0,0xf7,0};
short head2[5]={0,0,0,0,0x800};
LWORD jj;
  int i;

  head1[3]=head2[2]=Width=m1;
  head1[4]=head2[3]=Height=m2;
  fwrite(head1,1,13,fp);
  for(i=0;i<256;i++){
    ByteBuf[0]=ByteBuf[1]=ByteBuf[2]=i;
    fwrite(ByteBuf,1,3,fp);
  }
  fputc(0x2c,fp);
  fwrite(head2,2,5,fp);
  ByteCount = ShiftBits = TempCode = 0;

  Encode = 258;  RunBits = 9;  MaxCodeSize =512;
  for(i = 0; i < 4999; i++) EncodeTable[i] = 0;
  Code = 256;
  FillBlockBuf();
  for(Rows = 0; Rows < Height; Rows++)  {
    jj=(m2-1-Rows)*m1;
    for(i=0;i<m1;i++)ByteBuf[i]=c256[jj++];
    if(Rows == 0) { PrefixCode = ByteBuf[0];  Dots = 1; }
    else Dots = 0;
    while( Dots < Width)  {
      SuffixCode = ByteBuf[Dots++];
      RandomIndex = PrefixCode ^ (SuffixCode << 4);
      if(RandomIndex == 0)  Val = 1;
      else Val = 4999 - RandomIndex;
      while(1)  {
        if(EncodeTable[RandomIndex] == 0)  {
          Code = PrefixCode;
          FillBlockBuf();
          if(Encode == 4096)  {
            Code = 256;
            FillBlockBuf();
            Encode = 258;  RunBits = 9;  MaxCodeSize =512;
            for(i = 0; i < 4999; i++) EncodeTable[i] = 0;
          }
          else  {
            if(Encode == MaxCodeSize)  {
              MaxCodeSize <<= 1;
              RunBits++;
            }
            PrefixTable[RandomIndex] = PrefixCode;
            SuffixTable[RandomIndex] = (unsigned char)SuffixCode;
            EncodeTable[RandomIndex] = Encode++;
          }
          PrefixCode = SuffixCode;
          break;
        }
        if(PrefixTable[RandomIndex] == PrefixCode &&
           SuffixTable[RandomIndex] == SuffixCode)  {
          PrefixCode = EncodeTable[RandomIndex];
          break;
        }
        else  {
          RandomIndex -= Val;
          if(RandomIndex < 0)  RandomIndex += 4999;
        }
      }
    }
  }
  Code = PrefixCode;
  FillBlockBuf();
  Code = 257;
  FillBlockBuf();
  if(ShiftBits > 0 || ByteCount > 0)   {
    BlockBuf[++ByteCount] = TempCode & 0x00FF;
    BlockBuf[0] = (unsigned char)ByteCount;
    fwrite(BlockBuf, 1, ByteCount+1, fp);
    ByteCount = 0;
  }
  fputc(0, fp);  fputc(';', fp);
}


