/* static char szModuleName__ []  = "c:/unix/new/shft.c"; */
/* static char szLastVersion []   = "Version 0.4"; */
/* static char szLastSave []      = "1994-07-05*17:59"; */
/* --------------------------------- shft.c --------------------------------- */

/*       bufrl - RL-algorithm for bufr encoding                               */
/*       clbit - store the last character to close the bit stream             */
/*       repar - read parameter file                                          */
/*       repix - read data in pixel format                                    */
/*       stbit - store bits into character                                    */

/*       exbit - extract bits from character                                  */
/*       wrpar - write parameter file                                         */
/*       wrpix - write data in pixel format                                   */

/*       sgbit - change the signed integer                                    */

/* -------------------------------------------------------------------------- */

#ifdef ENCBUF
/* -------------------------------------------------------------------------- */

int bufrl(bcol,bncol,cor,cou,bncg,bnnp,ntp)
int *bcol;
int bncol;
int *cor;
int *cou;
int *bncg;
int *bnnp;
int *ntp;
{
  extern int wcol[],wcou[];
  unsigned char sw; 
  int ntc,nc,nt,n,m;

  n=1;
  ntc=1;
  sw=0;
  wcol[ntc]=bcol[n];
  wcou[ntc]=1;
  while(sw == 0)
  { 
    n=n+1;
    if(n > bncol)
    { 
      if(wcou[ntc] != 1)
      { 
        if(wcou[ntc] > nclim+1)
        { 
          wcou[ntc]=wcou[ntc]-1;
          ntc=ntc+1;
          wcou[ntc]=1;
          wcol[ntc]=wcol[ntc-1];
        }
        else
        { 
          m=wcou[ntc]-1;
          for(n=0;n<=m;n++)
          { 
            wcou[ntc+n]=1; 
            wcol[ntc+n]=wcol[ntc];
          }
          ntc=ntc+m;
        }
      }
      sw=1;
    }
    else
    { 
      if(bcol[n] == wcol[ntc])
      { 
        if(wcou[ntc] == rpf)
        { 
          ntc=ntc+1; 
          wcou[ntc]=1; 
          wcol[ntc]=bcol[n];
        }
        else wcou[ntc]=wcou[ntc]+1;
      }  
      else
      { 
        if((wcou[ntc] > 1) && (wcou[ntc] <= nclim))
        { 
          m=wcou[ntc]-1;
          for(n=0;n<=m;n++) 
          { 
            wcou[ntc+n]=1;
            wcol[ntc+n]=wcol[ntc];
          }
          ntc=ntc+m;
          sw=1;
        }
        ntc=ntc+1;
        wcol[ntc]=bcol[n];
        wcou[ntc]=1;
      }
    }
  }
  n=1;
  nt=1;
  while(sw == 1)
  { 
    sw=0;
    nc=1;
    cou[nt]=wcou[n];
    cor[nt]=wcol[n];
m1: n=n+1;
    if(n <= ntc)
    { 
      nt=nt+1;
      if(wcou[n] > 1)
      { 
        if(nc != rpf)
        { 
          nc=nc+1;
          cou[nt]=wcou[n];
          cor[nt]=wcol[n];
        }
        else
        { 
          cou[nt]=1; 
          cor[nt]=wcol[n];
          nt=nt+1;
          cou[nt]=wcou[n]-1;
          cor[nt]=wcol[n];
          if(cou[nt] == 1) goto m2;
          nc=1;
        }
        goto m1;
      }
      else
      { 
        cou[nt]=wcou[n]; 
        cor[nt]=wcol[n];
m2:     n=n+1;
        if(n <= ntc)
        { 
          nt=nt+1;
          if(wcou[n] <= 1)
          { 
            cou[nt]=wcou[n];
            cor[nt]=wcol[n];
            goto m2;
          }
          sw=1;
        }
      }
    }
  }
  *ntp=1;
  n=2;
  bncg[*ntp]=1;
  while(sw == 0)
  { 
    if(cou[n] != 1)
    { 
      bncg[*ntp]=bncg[*ntp]+1; 
      n=n+1;
    }
    else
    { 
      bnnp[*ntp]=1;
      while(sw == 0)
      { 
        sw=1;
        n=n+1;
        if(n > nt) return(0);
        if(cou[n] == 1) bnnp[*ntp]=bnnp[*ntp]+1;
        if((cou[n] == 1) && (bnnp[*ntp] < rpf)) sw=0;
      }
      sw=0;
      if(cou[n] == 1)
      { 
        if(n == nt) return(0);
        if(n == nt-1) bnnp[*ntp]=bnnp[*ntp]-1;
        else n=n+1;
      }
      n=n+1;
      *ntp= *ntp+1; 
      bncg[*ntp]=1;
    }
  }
  return(0);
}

/* -------------------------------------------------------------------------- */

void clbit(ff,nfree,ch)
FILE *ff;
char *nfree;
unsigned char *ch;
{
  int ck;

  ck= *ch;
  if(*nfree < 8) fputc(ck,ff);
  *nfree=8;
}

/* -------------------------------------------------------------------------- */

int repar(ff,s) 
FILE *ff;
unsigned char *s; 
{
  fscanf(ff," Parameter File produced by C-Routine DECBUF or CRPIX\n");
  fscanf(ff," ====================================================\n");
  fscanf(ff," %3d%3d%3d",&d.trtim[1],&d.trtim[2],&d.trtim[3]);
  fscanf(ff," %2d%3d image transmission time\n",&d.trtim[4],&d.trtim[5]);
  fscanf(ff," %3d%3d%3d",&d.datim[1],&d.datim[2],&d.datim[3]);
  fscanf(ff," %2d%3d image production time\n",&d.datim[4],&d.datim[5]);
  fscanf(ff," ====================================================\n");
  fscanf(ff,"     %3d  I3   BUFR edition number\n",&b.bufred);
  fscanf(ff,"     %3d  I3   master table version number\n",&b.bufver);
  fscanf(ff,"     %3d  I3   local table version number\n",&b.locver);
  fscanf(ff,"  %6d  I6   originating centre\n",&b.iorg);
  fscanf(ff,"  %c%c%c%c%c%c ",&s[1],&s[2],&s[3],&s[4],&s[5],&s[6]);
  fscanf(ff," 6A1  ASCII original station & country\n");
  fscanf(ff,"   %5d  I6   number of pixels per row\n",&b.ntcols);
  fscanf(ff,"   %5d  I6   number of pixels per column\n",&b.ntlin);
  fscanf(ff,"  %6d",&b.ilat[1]);
  fscanf(ff,"  I6   latitude top left corner      [/100- 90]\n");
  fscanf(ff,"  %6d",&b.ilon[1]);
  fscanf(ff,"  I6   longitude top left corner     [/100-180]\n");
  fscanf(ff,"  %6d",&b.ilat[2]);
  fscanf(ff,"  I6   latitude top right corner     [/100- 90]\n");
  fscanf(ff,"  %6d",&b.ilon[2]);
  fscanf(ff,"  I6   longitude top right corner    [/100-180]\n");
  fscanf(ff,"  %6d",&b.ilat[3]);
  fscanf(ff,"  I6   latitude bottom right corner  [/100- 90]\n");
  fscanf(ff,"  %6d",&b.ilon[3]);
  fscanf(ff,"  I6   longitude bottom right corner [/100-180]\n");
  fscanf(ff,"  %6d",&b.ilat[4]);
  fscanf(ff,"  I6   latitude bottom left corner   [/100- 90]\n");
  fscanf(ff,"  %6d",&b.ilon[4]);
  fscanf(ff,"  I6   longitude bottom left corner  [/100-180]\n");
  fscanf(ff,"       %1d  I1   projection type\n",&b.iproj);
  fscanf(ff,"  %6d",&b.ilat1);
  fscanf(ff,"  I6   latitude 1st standard parallel [/100-90]\n");
  fscanf(ff,"  %6d",&b.ilat2);
  fscanf(ff,"  I6   latitude 2nd standard parallel [/100-90]\n");
  fscanf(ff,"  %6d",&b.isizeh);
  fscanf(ff,"  I6   pixel size at lat.of std.parallel  [*10]\n");
  fscanf(ff,"  %6d",&b.isizev);
  fscanf(ff,"  I6   pixel size at mean longitude       [*10]\n");
  fscanf(ff,"      %2d  I2   picture type\n",&b.ipict);
  fscanf(ff,"  %6d  I6   data combination\n",&b.icomb);
  fscanf(ff,"       %1d  I1   coordinate grid type\n",&b.igrid);
  fscanf(ff,"      %2d  I2   calibration method\n",&b.ical);
  fscanf(ff,"      %2d  I2   clutter treatment\n",&b.iclutt);
  fscanf(ff,"       %1d  I1   occultation correction\n",&b.ioccul);
  fscanf(ff,"       %1d  I1   range att. correction\n",&b.irange);
  fscanf(ff,"       %1d  I1   bright band correction\n",&b.ibrigh);
  fscanf(ff,"       %1d  I1   radome att. correction\n",&b.iradom);
  fscanf(ff,"    %4d",&b.iclair);
  fscanf(ff,"  I4   clear air att. correction      [/1e5]\n");
  fscanf(ff,"       %1d  I1   precipitation att. correction\n",&b.iprec);
  fscanf(ff,"       %1d  I1   Z-R-conversion type\n",&b.izr);
  fscanf(ff,"   %5d  I5   Z-R-conversion factor\n",&b.ifaczr);
  fscanf(ff,"    %4d",&b.iexpzr);
  fscanf(ff,"  I4   Z-R-conversion exponent        [/100]\n");
  fscanf(ff,"     %3d  I3   number of pixel values\n",&b.ntpixv);
  fscanf(ff," %7d",&b.ibotvl);
  fscanf(ff,"  I7   bottom rainrate pixel value 0     [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[1]);
  fscanf(ff,"  I7   top rainrate pixel value 0        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[2]);
  fscanf(ff,"  I7   top rainrate pixel value 1        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[3]);
  fscanf(ff,"  I7   top rainrate pixel value 2        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[4]);
  fscanf(ff,"  I7   top rainrate pixel value 3        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[5]);
  fscanf(ff,"  I7   top rainrate pixel value 4        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[6]);
  fscanf(ff,"  I7   top rainrate pixel value 5        [/1e7]\n");
  /* BBN - Top value 6 - 16 added   */
  fscanf(ff," %7d",&b.itopvl[7]);
  fscanf(ff,"  I7   top rainrate pixel value 6        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[8]);
  fscanf(ff,"  I7   top rainrate pixel value 7        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[9]);
  fscanf(ff,"  I7   top rainrate pixel value 8        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[10]);
  fscanf(ff,"  I7   top rainrate pixel value 9        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[11]);
  fscanf(ff,"  I7   top rainrate pixel value 10        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[12]);
  fscanf(ff,"  I7   top rainrate pixel value 11        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[13]);
  fscanf(ff,"  I7   top rainrate pixel value 12        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[14]);
  fscanf(ff,"  I7   top rainrate pixel value 13        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[15]);
  fscanf(ff,"  I7   top rainrate pixel value 14        [/1e7]\n");
  fscanf(ff," %7d",&b.itopvl[16]);
  fscanf(ff,"  I7   top rainrate pixel value 15        [/1e7]\n");
  return(0);
}

/* -------------------------------------------------------------------------- */

void repix(ff,rcol,jcol) 
FILE *ff;
int *rcol;
int jcol; 
{
  unsigned char ch;
  int j;

  for(j=1;j<=jcol;j++) 
  { 
    ch=fgetc(ff);
    rcol[j]=ch;
  }
}

/* -------------------------------------------------------------------------- */

void stbit(ff,dat,nbit,nfree,ch)
FILE *ff;
int dat,nbit;
char *nfree;
unsigned char *ch;
{
  extern unsigned char bit[];
  unsigned char cdat;
  int ck,jbit;

  jbit=nbit;
  while(jbit > 0) 
  { 
    if(*nfree == 8) *ch=0;
    jbit=nbit-8;
    if(jbit > 0) nbit=8;
    if(jbit < 0) jbit=0;
    cdat=(dat >> jbit) & bit[nbit];
    if(*nfree >= nbit)
    { 
      *nfree= *nfree-nbit;
      *ch= *ch | (cdat << *nfree);
      if(*nfree == 0) *nfree=8;
    }
    else
    { 
      ck= *ch | (cdat >> (nbit- *nfree)); 
      fputc(ck,ff);
      *nfree=8+ *nfree-nbit;
      *ch=cdat << *nfree;
    }
    ck= *ch;
    if(*nfree == 8) fputc(ck,ff);
    nbit=jbit;
  }
}

/* -------------------------------------------------------------------------- */

#else

/* -------------------------------------------------------------------------- */

void exbit(ff,dat,nbit,nfree,ch)
FILE *ff;
int *dat,nbit;
char *nfree;
unsigned char *ch;  
{
  extern unsigned char bit[];
  unsigned char shft,ws;
  int jbit;
  
  *dat=0;
  shft=0;
  jbit=nbit;
  while(jbit > 0)
  { 
    if(*nfree == 8) *ch=fgetc(ff);
    jbit=nbit-8;
    if(jbit > 0) nbit=8;
    if(*nfree >= nbit)
    { 
      *nfree= *nfree-nbit; 
      ws=(*ch >> *nfree) & bit[nbit];
      if(*nfree == 0) *nfree=8;
    }
    else
    { 
      ws= *ch & bit[*nfree]; 
      *ch=fgetc(ff);
	  *nfree=8+ *nfree-nbit;
      ws=(ws << (8- *nfree)) | ((*ch >> *nfree) & bit[8- *nfree]);
    }
    *dat= (*dat << shft) | ws;
    shft=8;
    if(jbit-8 < 0) shft=jbit;
    nbit=jbit;
  }
}

/* -------------------------------------------------------------------------- */

int wrpar(ff,s) 
FILE *ff;
unsigned char *s;
{
  fprintf(ff," Parameter File produced by C-Routine DECBUF or CRPIX\n");
  fprintf(ff," ====================================================\n");
  fprintf(ff," %3d%3d%3d",d.trtim[1],d.trtim[2],d.trtim[3]);
  fprintf(ff," %2d%3d image transmission time\n",d.trtim[4],d.trtim[5]);
  fprintf(ff," %3d%3d%3d",d.datim[1],d.datim[2],d.datim[3]);
  fprintf(ff," %2d%3d image production time\n",d.datim[4],d.datim[5]);
  fprintf(ff," ====================================================\n");
  fprintf(ff,"     %3d  I3   BUFR edition number\n",b.bufred);
  fprintf(ff,"     %3d  I3   master table version number\n",b.bufver);
  fprintf(ff,"     %3d  I3   local table version number\n",b.locver);
  fprintf(ff,"  %6d  I6   originating centre\n",b.iorg);
  fprintf(ff,"  %c%c%c%c%c%c ",s[1],s[2],s[3],s[4],s[5],s[6]);
  fprintf(ff," 6A1  ASCII original station & country\n");
  fprintf(ff,"   %5d  I6   number of pixels per row\n",b.ntcols);
  fprintf(ff,"   %5d  I6   number of pixels per column\n",b.ntlin);
  fprintf(ff,"  %6d",b.ilat[1]);
  fprintf(ff,"  I6   latitude top left corner      [/100- 90]\n");
  fprintf(ff,"  %6d",b.ilon[1]);
  fprintf(ff,"  I6   longitude top left corner     [/100-180]\n");
  fprintf(ff,"  %6d",b.ilat[2]);
  fprintf(ff,"  I6   latitude top right corner     [/100- 90]\n");
  fprintf(ff,"  %6d",b.ilon[2]);
  fprintf(ff,"  I6   longitude top right corner    [/100-180]\n");
  fprintf(ff,"  %6d",b.ilat[3]);
  fprintf(ff,"  I6   latitude bottom right corner  [/100- 90]\n");
  fprintf(ff,"  %6d",b.ilon[3]);
  fprintf(ff,"  I6   longitude bottom right corner [/100-180]\n");
  fprintf(ff,"  %6d",b.ilat[4]);
  fprintf(ff,"  I6   latitude bottom left corner   [/100- 90]\n");
  fprintf(ff,"  %6d",b.ilon[4]);
  fprintf(ff,"  I6   longitude bottom left corner  [/100-180]\n");
  fprintf(ff,"       %1d  I1   projection type\n",b.iproj);
  fprintf(ff,"  %6d",b.ilat1);
  fprintf(ff,"  I6   latitude 1st standard parallel [/100-90]\n");
  fprintf(ff,"  %6d",b.ilat2);
  fprintf(ff,"  I6   latitude 2nd standard parallel [/100-90]\n");
  fprintf(ff,"  %6d",b.isizeh);
  fprintf(ff,"  I6   pixel size at lat.of std.parallel  [*10]\n");
  fprintf(ff,"  %6d",b.isizev);
  fprintf(ff,"  I6   pixel size at mean longitude       [*10]\n");
  fprintf(ff,"      %2d  I2   picture type\n",b.ipict);
  fprintf(ff,"  %6d  I6   data combination\n",b.icomb);
  fprintf(ff,"       %1d  I1   coordinate grid type\n",b.igrid);
  fprintf(ff,"      %2d  I2   calibration method\n",b.ical);
  fprintf(ff,"      %2d  I2   clutter treatment\n",b.iclutt);
  fprintf(ff,"       %1d  I1   occultation correction\n",b.ioccul);
  fprintf(ff,"       %1d  I1   range att. correction\n",b.irange);
  fprintf(ff,"       %1d  I1   bright band correction\n",b.ibrigh);
  fprintf(ff,"       %1d  I1   radome att. correction\n",b.iradom);
  fprintf(ff,"    %4d",b.iclair);
  fprintf(ff,"  I4   clear air att. correction         [/1e5]\n");
  fprintf(ff,"       %1d  I1   precipitation att. correction\n",b.iprec);
  fprintf(ff,"       %1d  I1   Z-R-conversion type\n",b.izr);
  fprintf(ff,"   %5d  I5   Z-R-conversion factor\n",b.ifaczr);
  fprintf(ff,"    %4d",b.iexpzr);
  fprintf(ff,"  I4   Z-R-conversion exponent           [/100]\n");
  fprintf(ff,"     %3d  I3   number of pixel values\n",b.ntpixv);
  fprintf(ff," %7d",b.ibotvl);
  fprintf(ff,"  I7   bottom rainrate pixel value 0     [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[1]);
  fprintf(ff,"  I7   top rainrate pixel value 0        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[2]);
  fprintf(ff,"  I7   top rainrate pixel value 1        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[3]);
  fprintf(ff,"  I7   top rainrate pixel value 2        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[4]);
  fprintf(ff,"  I7   top rainrate pixel value 3        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[5]);
  fprintf(ff,"  I7   top rainrate pixel value 4        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[6]);
  fprintf(ff,"  I7   top rainrate pixel value 5        [/1e7]\n");
  /* BBN - Top value 6 - 16 added   */
  fprintf(ff," %7d",b.itopvl[7]);
  fprintf(ff,"  I7   top rainrate pixel value 6        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[8]);
  fprintf(ff,"  I7   top rainrate pixel value 7        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[9]);
  fprintf(ff,"  I7   top rainrate pixel value 8        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[10]);
  fprintf(ff,"  I7   top rainrate pixel value 9        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[11]);
  fprintf(ff,"  I7   top rainrate pixel value 10        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[12]);
  fprintf(ff,"  I7   top rainrate pixel value 11        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[13]);
  fprintf(ff,"  I7   top rainrate pixel value 12        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[14]);
  fprintf(ff,"  I7   top rainrate pixel value 13        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[15]);
  fprintf(ff,"  I7   top rainrate pixel value 14        [/1e7]\n");
  fprintf(ff," %7d",b.itopvl[16]);
  fprintf(ff,"  I7   top rainrate pixel value 15        [/1e7]\n");
  fprintf(ff," END OF FILE\n"); 
  return(0);
}

/* -------------------------------------------------------------------------- */

void wrpix(ff,bcol,jcol) 
FILE *ff;
int *bcol;
int jcol; 
{
  int ch,j;

  for(j=1;j<=jcol;j++)
  { 
    ch=bcol[j];
    fputc(ch,ff);
  }
}

/* -------------------------------------------------------------------------- */

#endif

/* -------------------------------------------------------------------------- */

#ifdef ENCBUF
/* BBN - only to be included onece in NRAD      */
int sgbit(dat,nbit) 
int dat,nbit;
{
  char k;
  long int m,n;

  n=1; 
  for(k=1;k<nbit;k++) n=n << 1; m=n << 1;
  if(dat < 0) dat=dat+m;
  else if(dat > n) dat=dat-m; 
  return(dat);
}
#endif 
/* ----------------------------- end of shft.c ------------------------------ */
