#include <stdio.h>
#define  n  1000        /* assume:  max_data length */

short datt,px,py,lengt,shift,crc;       /* bar5.par's parameters */
short length;                           /* real length of bar */
unsigned char a[n],a1[n],a2[n];         /* read in 3 group data for one bar */

char pCode[80];         /* result, assume one bar < 80 chars */
long slip[400],la;      /* max black_white bar number */
long save[400];         /* as slip, due to choice more format */

main(ac,av)
int ac; char *av[];
{
  char  f1[30];
  short i,j,k,ip=0;
  FILE *fp0;

  if(ac<2){
    printf("\n\tUsage: bar51 batch_file [n]\n");
    printf("\n hint:  dir/b *.bmp >1.1    bar51 1.1\n");
    printf("\n\t                   jiang 20110511\n");
    printf("\n need a parameter file: bar5.par\n");
    printf("\n# for bar5, BMP 256 gray format");
    printf("\n0             ! data type: 0 -- raw;  1 -- colum");
    printf("\n505 243       ! start read point position (x,y)");
    printf("\n200           ! length");
    printf("\n5             ! if fail, shift 2_side n points, do again.");
    printf("\n1             ! 1 do_crc, 0 undo_crc. 128/upca:===1;  251:===0");
    printf("\n\n");
    exit(0);
  }
  fp0=fopen(av[1],"rb");
  if(fp0==0){ printf("\n\t input file not found !\n"); exit(0); }
  j=0; if(ac>2)sscanf(av[2],"%d",&j);
  readpar();
l10:
  fgets(f1,30,fp0); if(feof(fp0)!=0)goto l20;
  f1[strlen(f1)-2]=0;  ip++;
  if(j!=0 && j!=ip)goto l10;
  printf("%2d: %s   ",ip,f1);
  k=Bar5(f1);
  if(k>0)for(i=0;i<k;i++)printf("%c",pCode[i]);  else printf("%d  err! ",k);
  printf("\n");
  goto l10;
l20:
  fclose(fp0);
}

readpar()
{
  FILE *fp1;
  char a[80];
  int i;
  fp1=fopen("bar5.par","r");
  if(fp1==0){ printf("\n\t bar5.par not found!\n"); exit(0); }
l10:
  fgets(a,80,fp1); if(a[0]=='#')goto l10;
                   sscanf(a,"%d",&datt);
  fgets(a,80,fp1); sscanf(a,"%d %d",&px,&py);
  fgets(a,80,fp1); sscanf(a,"%d",&lengt);
  fgets(a,80,fp1); sscanf(a,"%d",&shift);
  fgets(a,80,fp1); sscanf(a,"%d",&crc);
  fclose(fp1);
  printf("position: %d %d\n",px,py);
}

#define space15  12
#define whitef0  200
Bar5(f1)
char *f1;
{
  short i,j, k, Width, Height, w;
  unsigned char dummy[3000];     /* assume MAX width of bmp file */
  long jj,kk;
  short barlen=0;
  FILE *fp;

  fp=fopen(f1,"rb");
  fseek(fp,10,0);
  fread(&kk,1,4,fp);
  fread(&jj,1,4,fp);            /* dummy */
  fread(&jj,1,4,fp);  Width=jj;
  fread(&jj,1,4,fp);  Height=jj;
  fread(&jj,1,4,fp);  if((jj>>16)!=8)return(0);  /* not 256 level gray pic */
  w=((Width-1)/4+1)*4;
  for(i=0;i<lengt;i++){ a[i]=a1[i]=a2[i]=0xff; }
  j=lengt;
  if(datt==1){
    if(j>Height)j=Height;
    jj=Height-j-py;   if(jj<0)jj=0;
    fseek(fp,kk+jj*w,0);
    for(i=0;i<j;i++){
      fread(dummy,1,w,fp);
      a[i]=dummy[px];
      if(px-shift>=0)a1[i]=dummy[px-shift];
      if(px+shift<Width)a2[i]=dummy[px+shift];
    }
  }
  if(datt==0){
    if(j>Width)j=Width;  k=px;  if(j+px>Width)k=Width-j;

    jj=Height-py-shift;
    if(jj>0){
      jj=jj*w+kk;  fseek(fp,jj,0);  fread(dummy,1,w,fp);
      for(i=0;i<j;i++)a1[i]=dummy[i+k];
    }

    jj=Height-py;
    if(jj>0){
      jj=jj*w+kk;  fseek(fp,jj,0);  fread(dummy,1,w,fp);
      for(i=0;i<j;i++) a[i]=dummy[i+k];
    }

    jj=Height-py+shift;
    if(jj>0 && jj<Height){
      jj=jj*w+kk;  fseek(fp,jj,0);  fread(dummy,1,w,fp);
      for(i=0;i<j;i++)a2[i]=dummy[i+k];
    }
  }
  length=j;
  fclose(fp);
  j=0;
  for(i=length/2;i<length;i++){          /* clear right hand */
    if(j==255){ a[i]=a1[i]=a2[i]=j; continue; }
    if(a[i]>whitef0)j++; else j=0;
    if(j>=space15)j=255;
  }
  j=0;
  for(i=length/2;i>=0;i--){             /* clear left  hand */
    if(j==255){ a[i]=a1[i]=a2[i]=j; continue; }
    if(a[i]>whitef0)j++; else j=0;
    if(j>=space15)j=255;
  }
/*for(i=0;i<length;i++)printf("%2x %2x %2x\n",a1[i],a[i],a2[i]); */
  barlen=BarCode(a);
  if(shift) {
    if(barlen<=0){ printf("%d  ",barlen);  barlen=BarCode(a1); }
    if(barlen<=0){ printf("%d  ",barlen);  barlen=BarCode(a2); }
  }

  if(barlen<=0){
    barlen=BarCode1(a);
    if(shift) {
      if(barlen<=0){ printf("%d  ",barlen);  barlen=BarCode1(a1); }
      if(barlen<=0){ printf("%d  ",barlen);  barlen=BarCode1(a2); }
    }
  }

  return(barlen);
}

/* -------------------------------- */

#define m60 55*4
#define m40 32*4
BarCode(unsigned char *b)
{
  short  i,j,k,zm,nbar;

  j=m60; k=0;
  for(i=0;i<length;i++) b[i]=255-b[i];     /* white_blck reverse */
/*  for(i=0;i<length;i++)printf("%d ",b[i]); printf("\n");       */
  for(i=10;i<length-10;i++){
    if(b[i]>=m40){                         /* find high peak's min */
      if(b[i]>=b[i-1] && b[i]>=b[i+1] && b[i]<j)j=b[i];
    } else {                               /*  find low peak's min */
      if(b[i]<=b[i-1] && b[i]<=b[i+1] && b[i]>k)k=b[i];
    }
  }
  zm=(j+k)/2;
/* printf("min_high_peak,max_low_peak,threshold: %d %d %d\n",j,k,zm); */
  k=nbar=0;
  for(i=0;i<length;i++){
    if(k==0 && b[i]<zm)continue;    /* pass white_head */
    if(k==0){ save[nbar++]=calm(b,i,zm); k=1; }
    if(k==1){
      if(b[i]<zm){ save[nbar++]=calm(b,i,zm)-1; k=2; }
      continue;
    }
    if(k==2) if(b[i]>zm){ save[nbar++]=calm(b,i,zm); k=1; }
  }
  nbar--;
  if(nbar>=59 && (nbar%8 )==3){ k=barupca(nbar);
                       if(k>0){ printf(" upc_a: ");   return(k); }}
  if(nbar>=49 && (nbar%10)==9){ k=bar39(nbar);
                       if(k>0){ printf(" 39code: ");  return(k); }}
  if(nbar>=19 && (nbar%6 )==1){ k=bar128(nbar);
                       if(k>0){ printf(" 128code: "); return(k); }}
  if(nbar>=21 && (nbar%10)==1){ k=bar251(nbar);
                       if(k>0){ printf(" 251code: "); return(k); }}
  if(nbar>=17 && (nbar%10)==7){ k=bar252(nbar);
                       if(k>0){ printf(" 252code: "); return(k); }}
  if(nbar<17)k=-6; else k=-7;
  return(k);
}

long mtab[108]={ 0x212222, 0x222122, 0x222221, 0x121223, 0x121322, 0x131222,
       0x122213, 0x122312, 0x132212, 0x221213, 0x221312, 0x231212, 0x112232,
       0x122132, 0x122231, 0x113222, 0x123122, 0x123221, 0x223211, 0x221132,
       0x221231, 0x213212, 0x223112, 0x312131, 0x311222, 0x321122, 0x321221,
       0x312212, 0x322112, 0x322211, 0x212123, 0x212321, 0x232121, 0x111323,
       0x131123, 0x131321, 0x112313, 0x132113, 0x132311, 0x211313, 0x231113,
       0x231311, 0x112133, 0x112331, 0x132131, 0x113123, 0x113321, 0x133121,
       0x313121, 0x211331, 0x231131, 0x213113, 0x213311, 0x213131, 0x311123,
       0x311321, 0x331121, 0x312113, 0x312311, 0x332111, 0x314111, 0x221411,
       0x431111, 0x111224, 0x111422, 0x121124, 0x121421, 0x141122, 0x141221,
       0x112214, 0x112412, 0x122114, 0x122411, 0x142112, 0x142211, 0x241211,
       0x221114, 0x413111, 0x241112, 0x134111, 0x111242, 0x121142, 0x121241,
       0x114212, 0x124112, 0x124211, 0x411212, 0x421112, 0x421211, 0x212141,
       0x214121, 0x412121, 0x111143, 0x111341, 0x131141, 0x114113, 0x114311,
       0x411113, 0x411311, 0x113141, 0x114131, 0x311141, 0x411131, 0x211412,
       0x211214, 0x211232, 0x233111,           0x211133};
bar128(short nbar)
{
  short  i,j,k,zm, jp, checkcode, codesort;
  float  aa[6],bb;
  short  i1,i2,cc[6];

/*  printf("how many white_black_bar: %d\n",nbar); */
  if(nbar<19){  /* printf(" too short, no a bar data! "); */ return(-6); }
  if(nbar%6!=1) { /* printf(" Not a 128_code "); */ return(-5); }
  for(i=0;i<=nbar;i++)slip[i]=save[i];
  zm=(slip[nbar-1]-slip[0])/(11*(nbar/6));
/*  printf(" %d ",zm);  */
  for(i=1;i<=nbar;i++){     /*   too narrow "1" adjust */
    k=slip[i]-slip[i-1];
    if(k<(zm*3/4)){
      k=(zm-k)/2;
      slip[i]+=k;
      slip[i-1]-=k;
    }
  }
  for(i=0;i<nbar;i++)slip[i]=slip[i+1]-slip[i];
/*for(i=0;i<nbar;i++){ if(i%6==0)printf("\n"); printf("%ld ",slip[i]);  } */

  if(slip[3]<slip[nbar-4]){   /*  printf("bar revered! "); */
    for(i=0;i<nbar/2;i++) {
      la=slip[i]; slip[i]=slip[nbar-i-1]; slip[nbar-i-1]=la;
    }
  }
  for(i=0;i<nbar;i+=6){
    bb=(slip[i]+slip[i+1]+slip[i+2]+slip[i+3]+slip[i+4]+slip[i+5])/11.;
    i1=i2=0;
    for(j=i;j<i+6;j++){
      aa[i1]=slip[j]/bb+0.5;
/*      printf("%f ",aa[i1]);  */
      slip[j]=aa[i1];
      if(slip[j]==0)slip[j]=1;
      if(slip[j]>=5)slip[j]=4;
      i2+=slip[j];
      aa[i1++]-=slip[j];
    }
    if(i2==10 || i2==12){
      for(i1=0;i1<6;i1++)cc[i1]=i1;
      sort(aa,cc);
      if(i2==10)slip[i+cc[0]]++;
      if(i2==12)slip[i+cc[5]]--;
    }
  }

  for(i=jp=j=0;i<nbar;i+=6){
    la=0;
    for(k=0;k<6;k++){la<<=4; la+=slip[j++];}
    slip[jp++]=la;
  }
  jp--;
/*for(i=0;i<jp;i++)printf("%lx ",slip[i]); printf("\n");  */

/* ------- calbar -------- */
  checkcode=0; k=0;
  for(i=0;i<jp;i++){
    for(j=0;j<107;j++)if(slip[i]==mtab[j])goto l10;
/*    printf("error1:(no such code) %lx (%d) ",slip[i],i);  */
    return(-1);
l10:
/*      printf("%d ",j);  */
    slip[k++]=j;
  }
  k--;
  codesort=slip[0]-102;
  if(codesort<1 || codesort >3){
      printf("error2:(no head)  ");
    return(-2);
  }
  if(slip[k]!=106){
      printf("error3:(no end)  ");
    return(-3);
  }

  for(i=1;i<k;i++)checkcode+=slip[i-1]*(i-1);  checkcode+=slip[0];
  checkcode%=103;         /*   printf("checkcode: %d  ",checkcode);  */
  k--;
  if(checkcode!=slip[k]){
/*    printf("error4:(check code)  ");  */
    return(-4);
  }
  jp=0;
  for(i=1;i<k;i++) if(codesort==3){
    if(slip[i]>=100)codesort=2;
    else {
      pCode[jp++]=slip[i]/10+48;
      pCode[jp++]=slip[i]%10+48;
    }
  }  else {
    if(slip[i]==99)codesort=3;
    else pCode[jp++]=slip[i]+32;
  }
  return(jp);
}

calm(unsigned char *b, short i, short zm)
{
  if(b[i]==b[i-1])return i<<4;
  return  (i<<4)-((b[i]-zm)<<4)/(b[i]-b[i-1]);
}

sort(a,c)
float a[6]; short c[6];
{
  short i,j,k;
  float x;
  for(i=0;i<5;i++)for(j=i+1;j<6;j++)if(a[i]<a[j]){
    x=a[i]; a[i]=a[j]; a[j]=x;
    k=c[i]; c[i]=c[j]; c[j]=k;
  }
}

char code39[44]={'0','1','2','3','4','5','6','7','8','9',
                 'A','B','C','D','E','F','G','H','I','J',
                 'K','L','M','N','O','P','Q','R','S','T',
                 'U','V','W','X','Y','Z','+','-','*','/',
                 '%','$','.',' '};
short ma39[44]={0xa6d,0xd2b,0xb2b,0xd95,0xa6b,0xd35,0xb35,0xa5b,0xd2d,0xb2d,
                 0xd4b,0xb4b,0xda5,0xacb,0xd65,0xb65,0xa9b,0xd4d,0xb4d,0xacd,
                 0xd53,0xb53,0xda9,0xad3,0xd69,0xb69,0xab3,0xd59,0xb59,0xad9,
                 0xcab,0x9ab,0xcd5,0x96b,0xcb5,0x9b5,0x949,0x95b,0x96d,0x929,
                 0xa49,0x925,0xcad,0x9ad};

bar39(short nbar)
{
  short i,j,k,jp;

  if(nbar<49)return(-6);
  if(nbar%10!=9)return(-5);

  for(i=0;i<nbar;i++)slip[i]=save[i+1]-save[i];
/*    for(i=0;i<nbar;i++)printf("%ld ",slip[i]);  printf("\n"); */

  if(slip[2]>slip[nbar-3]){  /*  printf("bar reversed !\n");  */
    for(i=0;i<nbar/2;i++){
      la=slip[i]; slip[i]=slip[nbar-i-1]; slip[nbar-i-1]=la;
    }
  }

  for(i=jp=0;i<=nbar;i+=10)slip[jp++]=c39(&slip[i]);
/*for(i=0;i<jp;i++)printf("%lx ",slip[i]); printf("\n"); */

/* ------- calbar -------- */

  for(i=0;i<jp;i++){
    for(j=0;j<44;j++)if(slip[i]==ma39[j]){ slip[i]=code39[j]; goto l0;}
    return(-1);
l0: ;;
  }

  if(slip[0]!='*'   ) return(-2);
  if(slip[jp-1]!='*') return(-3);

/* calculate crc 39 code */
  for(i=1,k=0;i<jp-2;i++){
    for(j=0;j<44;j++)if(slip[i]==code39[j])break;  k+=j;
  }
  k%=43;
  for(j=0;j<44;j++)if(slip[jp-2]==code39[j])break;
  if(crc==1 && k!=j) return(-4);

  for(i=1,k=0;i<jp-1-crc;i++)pCode[k++]=slip[i];
  return(k);
}

c39(aa)
long *aa;
{
  short i,j,z;
  short a[9],b[9],c[9];
  for(i=0;i<9;i++){ a[i]=aa[i]; b[i]=i; c[i]=1; }
  for(i=0;i<8;i++)for(j=i+1;j<9;j++)if(a[i]<a[j]){
    z=a[i]; a[i]=a[j]; a[j]=z;
    z=b[i]; b[i]=b[j]; b[j]=z;
  }
  for(i=0;i<3;i++)c[b[i]]=2;
  for(i=0,z=0;i<10;i+=2){
    z<<=1; z++;
    if(c[i]==2) { z<<=1; z++; }
    if(i!=8)z<<=c[i+1];           /* last white not include */
  }
  return(z);
}

short bar25[10]={11221,21112,12112,22111,11212,21211,12211,11122,21121,12121};
bar251(short nbar)
{
  short i,j,k,jp;

  if(nbar<21) return(-6);
  if(nbar%10!=1) return(-5);

  for(i=0;i<nbar;i++)slip[i]=save[i+1]-save[i];
/*    for(i=0;i<nbar;i++)printf("%ld ",slip[i]);  printf("\n");    */

  if(slip[2]<slip[nbar-3]){    printf("bar reversed !\n");
    for(i=0;i<nbar/2;i++){
      la=slip[i]; slip[i]=slip[nbar-i-1]; slip[nbar-i-1]=la;
    }
  }

  for(i=6,jp=0;i<nbar-6;i+=10)slip[jp++]=std25(&slip[i]);
/*for(i=0;i<jp;i++)printf("%ld ",slip[i]); printf("\n"); */

/* ------- calbar -------- */
  for(i=0;i<jp;i++){
    for(j=0;j<10;j++)if(slip[i]==bar25[j]){ slip[i]=j+48;  goto l0; }
    return(-1);
l0: ;;
  }

  for(i=k=0;i<jp;i++)pCode[k++]=slip[i];
/* have not found how to calculate STD crc code yet !!! */
  return(k);
}

std25(aa)
long *aa;
{
  short i,j,z;
  short b[5],c[5],e[5];
  for(i=0;i<5;i++){ b[i]=i; c[i]=1; e[i]=aa[i*2]; }
  for(i=0;i<4;i++)for(j=i+1;j<5;j++)if(e[i]<e[j]){
    z=e[i]; e[i]=e[j]; e[j]=z;
    z=b[i]; b[i]=b[j]; b[j]=z;
  }
  for(i=0;i<2;i++)c[b[i]]=2;
  for(i=0,j=0;i<5;i++){ j*=10; j+=c[i]; }
  return(j);
}

bar252(short nbar)
{
  short i,j,k,jp;

  if(nbar<17) return(-6);
  if(nbar%10!=7)return(-5);

  for(i=0;i<nbar;i++)slip[i]=save[i+1]-save[i];
/*    for(i=0;i<nbar;i++)printf("%ld ",slip[i]);  printf("\n");    */

  if(slip[2]>slip[nbar-3]){    printf("bar reversed !\n");
    for(i=0;i<nbar/2;i++){
      la=slip[i]; slip[i]=slip[nbar-i-1]; slip[nbar-i-1]=la;
    }
  }

  for(i=4,jp=0;i<nbar-4;i+=10,jp+=2)itf25(&slip[i],&slip[jp]);
/*for(i=0;i<jp;i++)printf("%ld ",slip[i]); printf("\n"); */

/* ------- calbar -------- */

  for(i=0;i<jp;i++){
    for(j=0;j<10;j++)if(slip[i]==bar25[j]){ slip[i]=j+48;  goto l0; }
    return(-1);
l0: ;;
  }
/* calculate check code for ITF  */
  for(i=0,k=0;i<jp;i++){ j=slip[i]-48; k+=j; if(i%2==0)k+=j+j;  }
  if(crc==1 && (k%10)!=0 )return(-4);

  for(i=k=0;i<jp-crc;i++)pCode[k++]=slip[i];
  return(k);
}

itf25(a,d)
long *a,*d;
{
  short i,j,z;
  short b[10],c[10];
  for(i=0;i<10;i++){ b[i]=i; c[i]=1; }
  for(i=0;i<9;i++)for(j=i+1;j<10;j++)if(a[i]<a[j]){
    z=a[i]; a[i]=a[j]; a[j]=z;
    z=b[i]; b[i]=b[j]; b[j]=z;
  }
  for(i=0;i<4;i++)c[b[i]]=2;
  j=z=0;
  for(i=0;i<10;i+=2){
    j*=10; j+=c[i];
    z*=10; z+=c[i+1];
  }
  d[0]=j; d[1]=z;
}

barupca(short nbar)
{
  short i,i1,i2,jp,l=0;
  if(nbar<59) return(-6);               /* too short            */
  if(nbar%8 !=3)return(-5);             /* not upca   59+8+...  */

  for(i=0;i<nbar;i++)slip[i]=save[i+1]-save[i];
/*  for(i=0;i<nbar;i++)printf("%ld ",slip[i]);  printf(" ***%d\n",nbar); */
l10:  l++;
  jp=0; i1=3; i2=(nbar-11)/2;
  for(i=i1;i<i1+i2;i+=4)pCode[jp++]=upca(i);
  if(pCode[0]!=0 && l==1){
 for(i=0;i<nbar/2;i++){i1=slip[i]; i2=nbar-i-1; slip[i]=slip[i2]; slip[i2]=i1;}
    goto l10;                           /* reversed bar */
  }
  i1=i2+8;
  for(i=i1;i<i1+i2;i+=4)pCode[jp++]=upca(i);
  i1=i2=0;  jp--;
  for(i=0;i<jp;i+=2)i1+=pCode[i];
  for(i=1;i<jp;i+=2)i2+=pCode[i];
/* printf("%3d %3d %d  ",i1,i2,pCode[jp]);  */
  i1=i1*3+i2; i1%=10; if(i1)i1=10-i1;
/* printf("%d          ",i1);               */
  if(i1!=pCode[jp])return(-4);
  for(i=1;i<jp;i++)pCode[i-1]=pCode[i]+48; jp--;
  for(i=0;i<jp;i++)if(pCode[i]==58)return(-1);
  return(jp);
}

/*             0     1     2     3     4     5     6     7     8     9  */
int upc[10]={ 3211, 2221, 2122, 1411, 1132, 1231, 1114, 1312, 1213, 3112 };
upca(int ii)
{
  int i,j=0,k=0,jj[4];
  float x[4],y;
  for(j=ii;j<ii+4;j++)k+=slip[j];
  for(i=0,j=ii;j<ii+4;j++)x[i++]=(7.0*slip[j])/k;
  if(x[0]>3.){ y=(x[0]-3.)*.5;            x[1]+=y; x[0]=3.;  }
  if(x[1]>4.){ y=(x[1]-4.)*.5;  x[0]+=y;  x[2]+=y; x[1]=4.;  }
  if(x[2]>3.){ y=(x[2]-3.)*.5;  x[1]+=y;  x[3]+=y; x[2]=3.;  }
  if(x[3]>4.){ y=(x[3]-4.)*.5;  x[2]+=y;           x[3]=4.;  }
  for(i=0;i<4;i++)if(x[i]<1.){
    y=(1.-x[i])*.5;   x[i]=1.;
    if(i==0)x[i+1]-=y;    if(i==3)x[i-1]-=y;
    if(i==1 || i==2){  x[i-1]-=y; x[i+1]-=y; }
  }
/*   for(i=0;i<4;i++) printf("%6.1f",x[i]);  printf("\n");  */
  y=0.5;
l10:  j++;
  for(k=i=0;i<4;i++){ jj[i]=x[i]+y;  k+=jj[i]; }
  if(k<7){ y+=0.1; if(j<9)goto l10; }
  if(k>7){ y-=0.1; if(j<9)goto l10; }
  for(k=i=0;i<4;i++)k=k*10+jj[i];       /*   printf("%d ",k); */
  for(i=0;i<10;i++)if(k==upc[i])break;  /*   printf("*%d ",i); */
  return(i);
}


/* ---------------- 2011,5,12 add, ---------------- */

float xm[400];
float xalm(unsigned char *b, int i, float xm)
{
  float x;
  if(b[i]==b[i-1])return (i*1.0);
  x=b[i]-xm; x=i-x/(b[i]-b[i-1]);
  return  (x);
}

BarCode1(unsigned char *b)
{
  int  i,j,k,nbar,b0,b1;
  int  n180,n60;

  j=0; k=255;
  for(i=length/4;i<length*3/4;i++){ if(b[i]>j)j=b[i]; if(b[i]<k)k=b[i]; }
  n180=j-50; n60=k+50;             /*  printf("%d %d  ",n180,n60); */
  k=nbar=0;  j=n60;
  for(i=0;i<length;i++){
    b0=b[i]; b1=b[i+1];  if(b0>n180)b0=n180; if(b1<n60)b1=n60;
    if(k==0)if(b0>b1){ xm[nbar++]=(b0+j)*0.5; j=b0; k=1; }
    if(k==1)if(b0<b1){ xm[nbar++]=(b0+j)*0.5; j=b0; k=0; }
  }
  xm[nbar]=xm[nbar+1]=(n60+j)*0.5;
  k=nbar=0;
  for(i=0;i<length;i++){
    if(k==0 && b[i]<xm[nbar])continue;
    if(k==0){ save[nbar]=xalm(b,i,xm[nbar])*32.;  k=1; nbar++; }
    if(k==1){ if(b[i]<xm[nbar]){
              save[nbar]=xalm(b,i,xm[nbar])*32.;  k=2; nbar++; }
              continue;    }
    if(k==2) if(b[i]>xm[nbar]) {
              save[nbar]=xalm(b,i,xm[nbar])*32.;  k=1; nbar++; }
  }

  nbar--;
  if(nbar>=59 && (nbar%8 )==3){ k=barupca(nbar);
                       if(k>0){ printf(" upc_a: ");   return(k); }}
  if(nbar>=49 && (nbar%10)==9){ k=bar39(nbar);
                       if(k>0){ printf(" 39code: ");  return(k); }}
  if(nbar>=19 && (nbar%6 )==1){ k=bar128(nbar);
                       if(k>0){ printf(" 128code: "); return(k); }}
  if(nbar>=21 && (nbar%10)==1){ k=bar251(nbar);
                       if(k>0){ printf(" 251code: "); return(k); }}
  if(nbar>=17 && (nbar%10)==7){ k=bar252(nbar);
                       if(k>0){ printf(" 252code: "); return(k); }}
  if(nbar<17)k=-6; else k=-7;
  return(k);
}
