예제 #1
0
/*****Function to Write Data on LCD*****/
void lcd_wr_char(char letter)
{
	char temp1;
	temp1 = letter;
	temp1 = (temp1 & 0xF0);
	lcd_port &= 0x0F;
	lcd_port |= temp1;
	sbit(lcd_port,RS);
	cbit(lcd_port,RW);
	sbit(lcd_port,EN);
	_delay_ms(5);
	cbit(lcd_port,EN);

	letter = letter & 0x0F;
	letter = letter<<4;
	lcd_port &= 0x0F;
	lcd_port |= letter;
	sbit(lcd_port,RS);
	cbit(lcd_port,RW);
	sbit(lcd_port,EN);
	_delay_ms(5);
	cbit(lcd_port,EN);
}
/*****Function to Write Command on LCD*****/
void lcd_wr_command(unsigned char cmd)
{
	unsigned char temp;
	temp = cmd;
	temp = temp & 0xF0;
	lcd_port &= 0x0F;
	lcd_port |= temp;
	cbit(lcd_port,RS);
	cbit(lcd_port,RW);
	sbit(lcd_port,EN);
	_delay_ms(5);
	cbit(lcd_port,EN);
	
	cmd = cmd & 0x0F;
	cmd = cmd<<4;
	lcd_port &= 0x0F;
	lcd_port |= cmd;
	cbit(lcd_port,RS);
	cbit(lcd_port,RW);
	sbit(lcd_port,EN);
	_delay_ms(5);
	cbit(lcd_port,EN);
}
예제 #3
0
void lcd_set_4bit() 
{ 
 _delay_ms(1); 
 
 cbit(lcd_port,RS); //RS=0 --- Command Input 
 cbit(lcd_port,RW); //RW=0 --- Writing to LCD 
 lcd_port = 0x30; //Sending 3 in the upper nibble 
 sbit(lcd_port,EN); //Set Enable Pin 
 _delay_ms(5); //delay 
 cbit(lcd_port,EN); //Clear Enable Pin 
_delay_ms(1); 
 
 cbit(lcd_port,RS); //RS=0 --- Command Input 
 cbit(lcd_port,RW); //RW=0 --- Writing to LCD 
 lcd_port = 0x30; //Sending 3 in the upper nibble 
 sbit(lcd_port,EN); //Set Enable Pin 
 _delay_ms(5); //delay 
 cbit(lcd_port,EN); //Clear Enable Pin 
 
 _delay_ms(1); 
 
 cbit(lcd_port,RS); //RS=0 --- Command Input 
 cbit(lcd_port,RW); //RW=0 --- Writing to LCD 
 lcd_port = 0x30; //Sending 3 in the upper nibble 
 sbit(lcd_port,EN); //Set Enable Pin 
 _delay_ms(5); //delay 
 cbit(lcd_port,EN); //Clear Enable Pin 
 
 _delay_ms(1); 
 
 cbit(lcd_port,RS); //RS=0 --- Command Input 
 cbit(lcd_port,RW); //RW=0 --- Writing to LCD 
 lcd_port = 0x20; //Sending 2 in the upper nibble to initialize LCD 4-bit mode 
 sbit(lcd_port,EN); //Set Enable Pin 
 _delay_ms(5); //delay 
 cbit(lcd_port,EN); //Clear Enable Pin 
} 
예제 #4
0
// Write 32 bits to display register and latch
void writeDisplayData(uint32_t data)
{
	// shift out data
	for (uint8_t i = 0; i < 4; i++)
	{
		// send byte over SPI
		SPDR = data >> (8 * (3 - i));
		// wait for transmission complete
		while(!(SPSR & (1 << SPIF)));
	}

	// latch register data
	sbit(OUTPORT(DISP_LATCH_PORT), DISP_LATCH_BIT);
	_delay_us(10);
	cbit(OUTPORT(DISP_LATCH_PORT), DISP_LATCH_BIT);
}
예제 #5
0
g2int g2_gribend(unsigned char *cgrib)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_gribend 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
//
// ABSTRACT: This routine finalizes a GRIB2 message after all grids
//   and fields have been added.  It adds the End Section ( "7777" )
//   to the end of the GRIB message and calculates the length and stores
//   it in the appropriate place in Section 0.
//   This routine is used with routines "g2_create", "g2_addlocal", 
//   "g2_addgrid", and "g2_addfield" to create a complete GRIB2 message.
//   g2_create must be called first to initialize a new GRIB2 message.
//
// PROGRAM HISTORY LOG:
// 2002-10-31  Gilbert
//
// USAGE:    int g2_gribend(unsigned char *cgrib)
//   INPUT ARGUMENT:
//     cgrib    - Char array containing all the data sections added
//                be previous calls to g2_create, g2_addlocal, g2_addgrid,
//                and g2_addfield.
//
//   OUTPUT ARGUMENTS:      
//     cgrib    - Char array containing the finalized GRIB2 message
//
//   RETURN VALUES:
//     ierr     - Return code.
//              > 0 = Length of the final GRIB2 message in bytes.
//               -1 = GRIB message was not initialized.  Need to call
//                    routine g2_create first.
//               -2 = GRIB message already complete.  
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 7.
//
// REMARKS: This routine is intended for use with routines "g2_create", 
//          "g2_addlocal", "g2_addgrid", and "g2_addfield" to create a complete 
//          GRIB2 message.
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$
{

      g2int iofst,lencurr,len,ilen,isecnum;
      g2int   ierr,lengrib;
      static unsigned char G=0x47;       // 'G'
      static unsigned char R=0x52;       // 'R'
      static unsigned char I=0x49;       // 'I'
      static unsigned char B=0x42;       // 'B'
      static unsigned char seven=0x37;   // '7'
 
      ierr=0;
//
//  Check to see if beginning of GRIB message exists
//
      if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
        printf("g2_gribend: GRIB not found in given message.\n");
        ierr=-1;
        return (ierr);
      }
//
//  Get current length of GRIB message
//  
      gbit(cgrib,&lencurr,96,32);
//
//  Loop through all current sections of the GRIB message to
//  find the last section number.
//
      len=16;    // Length of Section 0
      for (;;) { 
      //    Get number and length of next section
        iofst=len*8;
        gbit(cgrib,&ilen,iofst,32);
        iofst=iofst+32;
        gbit(cgrib,&isecnum,iofst,8);
        len=len+ilen;
      //    Exit loop if last section reached
        if ( len == lencurr ) break;
      //    If byte count for each section doesn't match current
      //    total length, then there is a problem.
        if ( len > lencurr ) {
          printf("g2_gribend: Section byte counts don''t add to total.\n");
          printf("g2_gribend: Sum of section byte counts = %d\n",(int)len);
          printf("g2_gribend: Total byte count in Section 0 = %d\n",(int)lencurr);
          ierr=-3;
          return (ierr);
        }
      }
//
//  Can only add End Section (Section 8) after Section 7.
//
      if ( isecnum != 7 ) {
        printf("g2_gribend: Section 8 can only be added after Section 7.\n");
        printf("g2_gribend: Section %d was the last found in given GRIB message.\n",isecnum);
        ierr=-4;
        return (ierr);
      }
//
//  Add Section 8  - End Section
//
      //cgrib(lencurr+1:lencurr+4)=c7777
      cgrib[lencurr]=seven;
      cgrib[lencurr+1]=seven;
      cgrib[lencurr+2]=seven;
      cgrib[lencurr+3]=seven;

//
//  Update current byte total of message in Section 0
//
      lengrib=lencurr+4;
      sbit(cgrib,&lengrib,96,32);

      return (lengrib);

}
예제 #6
0
파일: misspack.c 프로젝트: khallock/LDM
void misspack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl,
              unsigned char *cpack, g2int *lcpack)
/*$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    misspack
//   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2000-06-21
//
// ABSTRACT: This subroutine packs up a data field using a complex
//   packing algorithm as defined in the GRIB2 documention.  It
//   supports GRIB2 complex packing templates with or without
//   spatial differences (i.e. DRTs 5.2 and 5.3).
//   It also fills in GRIB2 Data Representation Template 5.2 or 5.3 
//   with the appropriate values.
//   This version assumes that Missing Value Management is being used and that
//   1 or 2 missing values appear in the data.
//
// PROGRAM HISTORY LOG:
// 2000-06-21  Gilbert
//
// USAGE:    misspack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl,
//                    unsigned char *cpack, g2int *lcpack)
//   INPUT ARGUMENT LIST:
//     fld[]    - Contains the data values to pack
//     ndpts    - The number of data values in array fld[]
//     idrsnum  - Data Representation Template number 5.N
//                Must equal 2 or 3.
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.2 or 5.3
//                [0] = Reference value - ignored on input
//                [1] = Binary Scale Factor
//                [2] = Decimal Scale Factor
//                    .
//                    .
//                [6] = Missing value management
//                [7] = Primary missing value
//                [8] = Secondary missing value
//                    .
//                    .
//               [16] = Order of Spatial Differencing  ( 1 or 2 )
//                    .
//                    .
//
//   OUTPUT ARGUMENT LIST: 
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.3
//                [0] = Reference value - set by misspack routine.
//                [1] = Binary Scale Factor - unchanged from input
//                [2] = Decimal Scale Factor - unchanged from input
//                    .
//                    .
//     cpack    - The packed data field (character*1 array)
//     *lcpack   - length of packed field cpack().
//
// REMARKS: None
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$*/
{

      g2int  *ifld, *ifldmiss, *jfld;
      g2int  *jmin, *jmax, *lbit;
      static g2int zero=0;
      g2int  *gref, *gwidth, *glen;
      g2int  glength, grpwidth;
      g2int  i, n, iofst, imin, ival1, ival2, isd, minsd, nbitsd;
      g2int  nbitsgref, left, iwmax, ngwidthref, nbitsgwidth, ilmax;
      g2int  nglenref, nglenlast, nbitsglen, ij;
      g2int  j, missopt, nonmiss, itemp, maxorig, nbitorig, miss1, miss2;
      g2int  ngroups, ng, num0, num1, num2;
      g2int  imax, lg, mtemp, ier, igmax;
      g2int  kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref;
      g2float  rmissp, rmisss, bscale, dscale, rmin, temp;
      static g2int simple_alg = 0;
      static g2float alog2=0.69314718;       /*  ln(2.0) */
      static g2int one=1;
      
      bscale=int_power(2.0,-idrstmpl[1]);
      dscale=int_power(10.0,idrstmpl[2]);
      missopt=idrstmpl[6];
      if ( missopt != 1 && missopt != 2 ) {
         printf("misspack: Unrecognized option.\n");
         *lcpack=-1;
         return;
      }
      else {    /*  Get missing values */
         g2_rdieee(idrstmpl+7,&rmissp,1);
         if (missopt == 2) g2_rdieee(idrstmpl+8,&rmisss,1);
      }
/*
//  Find min value of non-missing values in the data,
//  AND set up missing value mapping of the field.
*/
      ifldmiss = calloc(ndpts,sizeof(g2int));
      rmin=1E+37;
      if ( missopt ==  1 ) {        /* Primary missing value only */
         for ( j=0; j<ndpts; j++) {
           if (fld[j] == rmissp) {
              ifldmiss[j]=1;
           }
           else {
              ifldmiss[j]=0;
              if (fld[j] < rmin) rmin=fld[j];
           }
         }
      }
      if ( missopt ==  2 ) {        /* Primary and secondary missing values */
         for ( j=0; j<ndpts; j++ ) {
           if (fld[j] == rmissp) {
              ifldmiss[j]=1;
           }
           else if (fld[j] == rmisss) {
              ifldmiss[j]=2;
           }
           else {
              ifldmiss[j]=0;
              if (fld[j] < rmin) rmin=fld[j];
           }
         }
      }
/*
//  Allocate work arrays:
//  Note: -ifldmiss[j],j=0,ndpts-1 is a map of original field indicating 
//         which of the original data values
//         are primary missing (1), sencondary missing (2) or non-missing (0).
//        -jfld[j],j=0,nonmiss-1 is a subarray of just the non-missing values 
//         from the original field.
*/
      /*if (rmin != rmax) { */
        iofst=0;
        ifld = calloc(ndpts,sizeof(g2int));
        jfld = calloc(ndpts,sizeof(g2int));
        gref = calloc(ndpts,sizeof(g2int));
        gwidth = calloc(ndpts,sizeof(g2int));
        glen = calloc(ndpts,sizeof(g2int));
        /*
        //  Scale original data
        */
        nonmiss=0;
        if (idrstmpl[1] == 0) {        /*  No binary scaling */
           imin=(g2int)rint(rmin*dscale);
           /*imax=(g2int)rint(rmax*dscale); */
           rmin=(g2float)imin;
           for ( j=0; j<ndpts; j++) {
              if (ifldmiss[j] == 0) {
                jfld[nonmiss]=(g2int)rint(fld[j]*dscale)-imin;
                nonmiss++;
              }
           }
        }
        else {                             /*  Use binary scaling factor */
           rmin=rmin*dscale;
           /*rmax=rmax*dscale; */
           for ( j=0; j<ndpts; j++ ) {
              if (ifldmiss[j] == 0) {
                jfld[nonmiss]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale);
                nonmiss++;
              }
           }
        }
        /*
        //  Calculate Spatial differences, if using DRS Template 5.3
        */
        if (idrsnum == 3) {        /* spatial differences */
           if (idrstmpl[16]!=1 && idrstmpl[16]!=2) idrstmpl[16]=2;
           if (idrstmpl[16] == 1) {      /* first order */
              ival1=jfld[0];
              for ( j=nonmiss-1; j>0; j--)
                 jfld[j]=jfld[j]-jfld[j-1];
              jfld[0]=0;
           }
           else if (idrstmpl[16] == 2) {      /* second order */
              ival1=jfld[0];
              ival2=jfld[1];
              for ( j=nonmiss-1; j>1; j--)
                 jfld[j]=jfld[j]-(2*jfld[j-1])+jfld[j-2];
              jfld[0]=0;
              jfld[1]=0;
           }
           /*
           //  subtract min value from spatial diff field
           */
           isd=idrstmpl[16];
           minsd=jfld[isd];
           for ( j=isd; j<nonmiss; j++ ) if ( jfld[j] < minsd ) minsd=jfld[j];
           for ( j=isd; j<nonmiss; j++ ) jfld[j]=jfld[j]-minsd;
           /*
           //   find num of bits need to store minsd and add 1 extra bit
           //   to indicate sign
           */
           temp=log((double)(abs(minsd)+1))/alog2;
           nbitsd=(g2int)ceil(temp)+1;
           /*
           //   find num of bits need to store ifld[0] ( and ifld[1]
           //   if using 2nd order differencing )
           */
           maxorig=ival1;
           if (idrstmpl[16]==2 && ival2>ival1) maxorig=ival2;
           temp=log((double)(maxorig+1))/alog2;
           nbitorig=(g2int)ceil(temp)+1;
           if (nbitorig > nbitsd) nbitsd=nbitorig;
           /*   increase number of bits to even multiple of 8 ( octet ) */
           if ( (nbitsd%8) != 0) nbitsd=nbitsd+(8-(nbitsd%8));
           /*
           //  Store extra spatial differencing info into the packed
           //  data section.
           */
           if (nbitsd != 0) {
              /*   pack first original value */
              if (ival1 >= 0) {
                 sbit(cpack,&ival1,iofst,nbitsd);
                 iofst=iofst+nbitsd;
              }
              else {
                 sbit(cpack,&one,iofst,1);
                 iofst=iofst+1;
                 itemp=abs(ival1);
                 sbit(cpack,&itemp,iofst,nbitsd-1);
                 iofst=iofst+nbitsd-1;
              }
              if (idrstmpl[16] == 2) {
               /*  pack second original value */
                 if (ival2 >= 0) {
                    sbit(cpack,&ival2,iofst,nbitsd);
                    iofst=iofst+nbitsd;
                 }
                 else {
                    sbit(cpack,&one,iofst,1);
                    iofst=iofst+1;
                    itemp=abs(ival2);
                    sbit(cpack,&itemp,iofst,nbitsd-1);
                    iofst=iofst+nbitsd-1;
                 }
              }
              /*  pack overall min of spatial differences */
              if (minsd >= 0) {
                 sbit(cpack,&minsd,iofst,nbitsd);
                 iofst=iofst+nbitsd;
              }
              else {
                 sbit(cpack,&one,iofst,1);
                 iofst=iofst+1;
                 itemp=abs(minsd);
                 sbit(cpack,&itemp,iofst,nbitsd-1);
                 iofst=iofst+nbitsd-1;
              }
           }
         /*print *,'SDp ',ival1,ival2,minsd,nbitsd*/
        }       /*  end of spatial diff section */
        /*
        //  Expand non-missing data values to original grid.
        */
        miss1=jfld[0];
        for ( j=0; j<nonmiss; j++) if (jfld[j] < miss1) miss1 = jfld[j];
        miss1--;
        miss2=miss1-1;
        n=0;
        for ( j=0; j<ndpts; j++) {
           if ( ifldmiss[j] == 0 ) {
              ifld[j]=jfld[n];
              n++;
           }
           else if ( ifldmiss[j] == 1 ) {
              ifld[j]=miss1;
           }
           else if ( ifldmiss[j] == 2 ) {
              ifld[j]=miss2;
           }
        }
        /*
        //   Determine Groups to be used.
        */
        if ( simple_alg == 1 ) {
           /*  set group length to 10 :  calculate number of groups */
           /*  and length of last group */
           ngroups=ndpts/10;
           for (j=0;j<ngroups;j++) glen[j]=10;
           itemp=ndpts%10;
           if (itemp != 0) {
              ngroups++;
              glen[ngroups-1]=itemp;
           }
        }
        else {
           /* Use Dr. Glahn's algorithm for determining grouping.
           */
           kfildo=6;
           minpk=10;
           inc=1;
           maxgrps=(ndpts/minpk)+1;
           jmin = calloc(maxgrps,sizeof(g2int));
           jmax = calloc(maxgrps,sizeof(g2int));
           lbit = calloc(maxgrps,sizeof(g2int));
           g2_pack_gp(&kfildo,ifld,&ndpts,&missopt,&minpk,&inc,&miss1,&miss2,
                        jmin,jmax,lbit,glen,&maxgrps,&ngroups,&ibit,&jbit,
                        &kbit,&novref,&lbitref,&ier);
           /*printf("SAGier = %d %d %d %d %d %d\n",ier,ibit,jbit,kbit,novref,lbitref);*/
           for ( ng=0; ng<ngroups; ng++) glen[ng]=glen[ng]+novref;
           free(jmin);
           free(jmax);
           free(lbit);
        }
        /*  
        //  For each group, find the group's reference value (min)
        //  and the number of bits needed to hold the remaining values
        */
        n=0;
        for ( ng=0; ng<ngroups; ng++) {
           /*  how many of each type? */
           num0=num1=num2=0;
           for (j=n; j<n+glen[ng]; j++) {
               if (ifldmiss[j] == 0 ) num0++;
               if (ifldmiss[j] == 1 ) num1++;
               if (ifldmiss[j] == 2 ) num2++;
           }
           if ( num0 == 0 ) {      /* all missing values */
              if ( num1 == 0 ) {       /* all secondary missing */
                gref[ng]=-2;
                gwidth[ng]=0;
              }
              else if ( num2 == 0 ) {       /* all primary missing */
                gref[ng]=-1;
                gwidth[ng]=0;
              }
              else {                          /* both primary and secondary */
                gref[ng]=0;
                gwidth[ng]=1;
              }
           }
           else {                      /* contains some non-missing data */
             /*    find max and min values of group */
             gref[ng]=2147483647;
             imax=-2147483647;
             j=n;
             for ( lg=0; lg<glen[ng]; lg++ ) {
                if ( ifldmiss[j] == 0 ) {
                  if (ifld[j] < gref[ng]) gref[ng]=ifld[j];
                  if (ifld[j] > imax) imax=ifld[j]; 
                }
                j++;
             }
             if (missopt == 1) imax=imax+1;
             if (missopt == 2) imax=imax+2;
             /*   calc num of bits needed to hold data */
             if ( gref[ng] != imax ) {
                temp=log((double)(imax-gref[ng]+1))/alog2;
                gwidth[ng]=(g2int)ceil(temp);
             }
             else {
                gwidth[ng]=0;
             }
           }
           /*   Subtract min from data */
           j=n;
           mtemp=(g2int)int_power(2.,gwidth[ng]);
           for ( lg=0; lg<glen[ng]; lg++ ) {
              if (ifldmiss[j] == 0)            /* non-missing */
                 ifld[j]=ifld[j]-gref[ng];
              else if (ifldmiss[j] == 1)         /* primary missing */
                 ifld[j]=mtemp-1;
              else if (ifldmiss[j] == 2)         /* secondary missing */
                 ifld[j]=mtemp-2;
              
              j++;
           }
           /*   increment fld array counter */
           n=n+glen[ng];
        }
        /*  
        //  Find max of the group references and calc num of bits needed 
        //  to pack each groups reference value, then
        //  pack up group reference values
        */
        /*printf(" GREFS: "); */
        /*for (j=0;j<ngroups;j++) printf(" %d",gref[j]); printf("\n"); */
        igmax=gref[0];
        for (j=1;j<ngroups;j++) if (gref[j] > igmax) igmax=gref[j];
        if (missopt == 1) igmax=igmax+1;
        if (missopt == 2) igmax=igmax+2;
        if (igmax != 0) {
           temp=log((double)(igmax+1))/alog2;
           nbitsgref=(g2int)ceil(temp);
           /* reset the ref values of any "missing only" groups. */
           mtemp=(g2int)int_power(2.,nbitsgref);
           for ( j=0; j<ngroups; j++ ) {
               if (gref[j] == -1) gref[j]=mtemp-1;
               if (gref[j] == -2) gref[j]=mtemp-2;
           }
           sbits(cpack,gref,iofst,nbitsgref,0,ngroups);
           itemp=nbitsgref*ngroups;
           iofst=iofst+itemp;
           /*         Pad last octet with Zeros, if necessary, */
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else {
           nbitsgref=0;
        }
        /*
        //  Find max/min of the group widths and calc num of bits needed
        //  to pack each groups width value, then
        //  pack up group width values
        */
        /*write(77,*)'GWIDTHS: ',(gwidth(j),j=1,ngroups)*/
        iwmax=gwidth[0];
        ngwidthref=gwidth[0];
        for (j=1;j<ngroups;j++) {
           if (gwidth[j] > iwmax) iwmax=gwidth[j];
           if (gwidth[j] < ngwidthref) ngwidthref=gwidth[j];
        }
        if (iwmax != ngwidthref) {
           temp=log((double)(iwmax-ngwidthref+1))/alog2;
           nbitsgwidth=(g2int)ceil(temp);
           for ( i=0; i<ngroups; i++) gwidth[i]=gwidth[i]-ngwidthref;
           sbits(cpack,gwidth,iofst,nbitsgwidth,0,ngroups);
           itemp=nbitsgwidth*ngroups;
           iofst=iofst+itemp;
           /*         Pad last octet with Zeros, if necessary,*/
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else {
           nbitsgwidth=0;
           for (i=0;i<ngroups;i++) gwidth[i]=0;
        }
        /*
        //  Find max/min of the group lengths and calc num of bits needed
        //  to pack each groups length value, then
        //  pack up group length values
        */
        /*printf(" GLENS: ");*/
        /*for (j=0;j<ngroups;j++) printf(" %d",glen[j]); printf("\n");*/
        ilmax=glen[0];
        nglenref=glen[0];
        for (j=1;j<ngroups-1;j++) {
           if (glen[j] > ilmax) ilmax=glen[j];
           if (glen[j] < nglenref) nglenref=glen[j];
        }
        nglenlast=glen[ngroups-1];
        if (ilmax != nglenref) {
           temp=log((double)(ilmax-nglenref+1))/alog2;
           nbitsglen=(g2int)ceil(temp);
           for ( i=0; i<ngroups-1; i++) glen[i]=glen[i]-nglenref;
           sbits(cpack,glen,iofst,nbitsglen,0,ngroups);
           itemp=nbitsglen*ngroups;
           iofst=iofst+itemp;
           /*         Pad last octet with Zeros, if necessary,*/
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else {
           nbitsglen=0;
           for (i=0;i<ngroups;i++) glen[i]=0;
        }
        /*
        //  For each group, pack data values
        */
        /*write(77,*)'IFLDS: ',(ifld(j),j=1,ndpts)*/
        n=0;
        ij=0;
        for ( ng=0; ng<ngroups; ng++) {
           glength=glen[ng]+nglenref;
           if (ng == (ngroups-1) ) glength=nglenlast;
           grpwidth=gwidth[ng]+ngwidthref;
       /*write(77,*)'NGP ',ng,grpwidth,glength,gref(ng)*/
           if ( grpwidth != 0 ) {
              sbits(cpack,ifld+n,iofst,grpwidth,0,glength);
              iofst=iofst+(grpwidth*glength);
           }
       /*  do kk=1,glength*/
       /*     ij=ij+1*/
       /*write(77,*)'SAG ',ij,fld(ij),ifld(ij),gref(ng),bscale,rmin,dscale*/
       /*  enddo*/
           n=n+glength;
        }
        /*         Pad last octet with Zeros, if necessary,*/
        if ( (iofst%8) != 0) {
           left=8-(iofst%8);
           sbit(cpack,&zero,iofst,left);
           iofst=iofst+left;
        }
        *lcpack=iofst/8;

        if ( ifld != 0 ) free(ifld);
        free(jfld);
        if ( ifldmiss != 0 ) free(ifldmiss);
        free(gref);
        free(gwidth);
        free(glen);
      /*}
      //else {          //   Constant field ( max = min )
      //  nbits=0;
      //  *lcpack=0;
      //  nbitsgref=0;
      //  ngroups=0;
      }*/

/*
//  Fill in ref value and number of bits in Template 5.2
*/
      mkieee(&rmin,idrstmpl+0,1);   /* ensure reference value is IEEE format*/
      idrstmpl[3]=nbitsgref;
      idrstmpl[4]=0;         /* original data were reals*/
      idrstmpl[5]=1;         /* general group splitting*/
      idrstmpl[9]=ngroups;          /* Number of groups*/
      idrstmpl[10]=ngwidthref;       /* reference for group widths*/
      idrstmpl[11]=nbitsgwidth;      /* num bits used for group widths*/
      idrstmpl[12]=nglenref;         /* Reference for group lengths*/
      idrstmpl[13]=1;                /* length increment for group lengths*/
      idrstmpl[14]=nglenlast;        /* True length of last group*/
      idrstmpl[15]=nbitsglen;        /* num bits used for group lengths*/
      if (idrsnum == 3) {
         idrstmpl[17]=nbitsd/8;      /* num bits used for extra spatial*/
                                     /* differencing values*/
      }

}
예제 #7
0
g2int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,g2int lcsec2)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_addlocal
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-01
//
// ABSTRACT: This routine adds a Local Use Section (Section 2) to
//   a GRIB2 message.  It is used with routines "g2_create",
//   "g2_addgrid", "g2_addfield",
//   and "g2_gribend" to create a complete GRIB2 message.
//   g2_create must be called first to initialize a new GRIB2 message.
//
// PROGRAM HISTORY LOG:
// 2002-11-01  Gilbert
//
// USAGE:    int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,
//                           g2int lcsec2)
//   INPUT ARGUMENTS:
//     cgrib    - Char array that contains the GRIB2 message to which section
//                2 should be added.
//     csec2    - Character array containing information to be added in
//                Section 2.
//     lcsec2   - Number of bytes of character array csec2 to be added to
//                Section 2.
//
//   OUTPUT ARGUMENT:
//     cgrib    - Char array to contain the updated GRIB2 message.
//                Must be allocated large enough to store the entire
//                GRIB2 message.
//
//   RETURN VALUES:
//     ierr     - Return code.
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.  Need to call
//                    routine gribcreate first.
//               -2 = GRIB message already complete.  Cannot add new section.
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 1 or 7.
//
// REMARKS: Note that the Local Use Section ( Section 2 ) can only follow
//          Section 1 or Section 7 in a GRIB2 message.
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$
{

      const unsigned char G=0x47;       // 'G'
      const unsigned char R=0x52;       // 'R'
      const unsigned char I=0x49;       // 'I'
      const unsigned char B=0x42;       // 'B'
      const unsigned char seven=0x37;   // '7'

      const g2int two=2;
      g2int   j,k,lensec2,iofst,ibeg,lencurr,ilen,len,istart;
      g2int   isecnum;

//
//  Check to see if beginning of GRIB message exists
//
      if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
        printf("g2_addlocal: GRIB not found in given message.\n");
        printf("g2_addlocal: Call to routine g2_create required to initialize GRIB message.\n");
        return(-1);
      }
//
//  Get current length of GRIB message
//
      gbit(cgrib,&lencurr,96,32);
//
//  Check to see if GRIB message is already complete
//
      if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven &&
           cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) {
        printf("g2_addlocal: GRIB message already complete.  Cannot add new section.\n");
        return(-2);
      }
//
//  Loop through all current sections of the GRIB message to
//  find the last section number.
//
      len=16;    // length of Section 0
      for (;;) {
      //    Get section number and length of next section
        iofst=len*8;
        gbit(cgrib,&ilen,iofst,32);
        iofst=iofst+32;
        gbit(cgrib,&isecnum,iofst,8);
        len=len+ilen;
      //    Exit loop if last section reached
        if ( len == lencurr ) break;
      //    If byte count for each section doesn't match current
      //    total length, then there is a problem.
        if ( len > lencurr ) {
          printf("g2_addlocal: Section byte counts don't add to total.\n");
          printf("g2_addlocal: Sum of section byte counts = %d\n",len);
          printf("g2_addlocal: Total byte count in Section 0 = %d\n",lencurr);
          return(-3);
        }
      }
//
//  Section 2 can only be added after sections 1 and 7.
//
      if ( (isecnum!=1) && (isecnum!=7) ) {
        printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n");
        printf("g2_addlocal: Section %d was the last found in given GRIB message.\n",isecnum);
        return(-4);
      }
//
//  Add Section 2  - Local Use Section
//
      ibeg=lencurr*8;        //   Calculate offset for beginning of section 2
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&two,iofst,8);     // Store section number ( 2 )
      istart=lencurr+5;
      //cgrib(istart+1:istart+lcsec2)=csec2(1:lcsec2)
      k=0;
      for (j=istart;j<istart+lcsec2;j++) {
         cgrib[j]=csec2[k++];
      }
      //
      //   Calculate length of section 2 and store it in octets
      //   1-4 of section 2.
      //
      lensec2=lcsec2+5;      // bytes
      sbit(cgrib,&lensec2,ibeg,32);

//
//  Update current byte total of message in Section 0
//
      lencurr+=lensec2;
      sbit(cgrib,&lencurr,96,32);

      return(lencurr);

}
예제 #8
0
파일: compack.c 프로젝트: ryandavid/rotobox
void compack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl,
             unsigned char *cpack,g2int *lcpack)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    compack
//   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2002-11-07
//
// ABSTRACT: This subroutine packs up a data field using a complex
//   packing algorithm as defined in the GRIB2 documentation.  It
//   supports GRIB2 complex packing templates with or without
//   spatial differences (i.e. DRTs 5.2 and 5.3).
//   It also fills in GRIB2 Data Representation Template 5.2 or 5.3 
//   with the appropriate values.
//
// PROGRAM HISTORY LOG:
// 2002-11-07  Gilbert
//
// USAGE:    void compack(g2float *fld,g2int ndpts,g2int idrsnum,
//                g2int *idrstmpl,unsigned char *cpack,g2int *lcpack)
//
//   INPUT ARGUMENTS:
//     fld[]    - Contains the data values to pack
//     ndpts    - The number of data values in array fld[]
//     idrsnum  - Data Representation Template number 5.N
//                Must equal 2 or 3.
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.2 or 5.3
//                [0] = Reference value - ignored on input
//                [1] = Binary Scale Factor
//                [2] = Decimal Scale Factor
//                    .
//                    .
//                [6] = Missing value management
//                [7] = Primary missing value
//                [8] = Secondary missing value
//                    .
//                    .
//               [16] = Order of Spatial Differencing  ( 1 or 2 )
//                    .
//                    .
//
//   OUTPUT ARGUMENTS: 
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.3
//                [0] = Reference value - set by compack routine.
//                [1] = Binary Scale Factor - unchanged from input
//                [2] = Decimal Scale Factor - unchanged from input
//                    .
//                    .
//     cpack    - The packed data field
//     lcpack   - length of packed field cpack.
//
// REMARKS: None
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$
{

      const g2int zero=0;
      g2int  *ifld,*gref,*glen,*gwidth;
      g2int  *jmin, *jmax, *lbit;
      g2int  i,j,n, /* nbits, */ imin,imax,left;
      g2int  isd,itemp,ilmax,ngwidthref=0,nbitsgwidth=0;
      g2int  nglenref=0,nglenlast=0,iofst,ival1,ival2;
      g2int  minsd,nbitsd=0,maxorig,nbitorig,ngroups;
      g2int  lg,ng,igmax,iwmax,nbitsgref;
      g2int  glength,grpwidth,nbitsglen=0;
      g2int  kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref;
      g2int  missopt, miss1, miss2, ier;
      g2float  bscale,dscale,rmax,rmin,temp;
      const g2int simple_alg = 0;
      const g2float alog2=0.69314718f;       //  ln(2.0)
      const g2int one=1;

      bscale=(float)int_power(2.0,-idrstmpl[1]);
      dscale=(float)int_power(10.0,idrstmpl[2]);
//
//  Find max and min values in the data
//
      rmax=fld[0];
      rmin=fld[0];
      for (j=1;j<ndpts;j++) {
        if (fld[j] > rmax) rmax=fld[j];
        if (fld[j] < rmin) rmin=fld[j];
      }

//
//  If max and min values are not equal, pack up field.
//  If they are equal, we have a constant field, and the reference
//  value (rmin) is the value for each point in the field and
//  set nbits to 0.
//
      if (rmin != rmax) {
        iofst=0;
        ifld=calloc(ndpts,sizeof(g2int));
        gref=calloc(ndpts,sizeof(g2int));
        gwidth=calloc(ndpts,sizeof(g2int));
        glen=calloc(ndpts,sizeof(g2int));
        //
        //  Scale original data
        //
        if (idrstmpl[1] == 0) {        //  No binary scaling
           imin=(g2int)RINT(rmin*dscale);
           //imax=(g2int)rint(rmax*dscale);
           rmin=(g2float)imin;
           for (j=0;j<ndpts;j++) 
              ifld[j]=(g2int)RINT(fld[j]*dscale)-imin;
        }
        else {                             //  Use binary scaling factor
           rmin=rmin*dscale;
           //rmax=rmax*dscale;
           for (j=0;j<ndpts;j++) 
             ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin)*bscale);
        }
        //
        //  Calculate spatial differences, if using DRS Template 5.3.
        //
        if (idrsnum == 3) {        // spatial differences
           if (idrstmpl[16]!=1 && idrstmpl[16]!=2) idrstmpl[16]=1;
           if (idrstmpl[16] == 1) {      // first order
              ival1=ifld[0];
              for (j=ndpts-1;j>0;j--) 
                 ifld[j]=ifld[j]-ifld[j-1];
              ifld[0]=0;
           }
           else if (idrstmpl[16] == 2) {      // second order
              ival1=ifld[0];
              ival2=ifld[1];
              for (j=ndpts-1;j>1;j--) 
                 ifld[j]=ifld[j]-(2*ifld[j-1])+ifld[j-2];
              ifld[0]=0;
              ifld[1]=0;
           }
           //
           //  subtract min value from spatial diff field
           //
           isd=idrstmpl[16];
           minsd=ifld[isd];
           for (j=isd;j<ndpts;j++)  if ( ifld[j] < minsd ) minsd=ifld[j];
           for (j=isd;j<ndpts;j++)  ifld[j]=ifld[j]-minsd;
           //
           //   find num of bits need to store minsd and add 1 extra bit
           //   to indicate sign
           //
           temp=(float)(log((double)(abs(minsd)+1))/alog2);
           nbitsd=(g2int)ceil(temp)+1;
           //
           //   find num of bits need to store ifld[0] ( and ifld[1]
           //   if using 2nd order differencing )
           //
           maxorig=ival1;
           if (idrstmpl[16]==2 && ival2>ival1) maxorig=ival2;
           temp=(float)(log((double)(maxorig+1))/alog2);
           nbitorig=(g2int)ceil(temp)+1;
           if (nbitorig > nbitsd) nbitsd=nbitorig;
           //   increase number of bits to even multiple of 8 ( octet )
           if ( (nbitsd%8) != 0) nbitsd=nbitsd+(8-(nbitsd%8));
           //
           //  Store extra spatial differencing info into the packed
           //  data section.
           //
           if (nbitsd != 0) {
              //   pack first original value
              if (ival1 >= 0) {
                 sbit(cpack,&ival1,iofst,nbitsd);
                 iofst=iofst+nbitsd;
              }
              else {
                 sbit(cpack,&one,iofst,1);
                 iofst=iofst+1;
                 itemp=abs(ival1);
                 sbit(cpack,&itemp,iofst,nbitsd-1);
                 iofst=iofst+nbitsd-1;
              }
              if (idrstmpl[16] == 2) {
               //  pack second original value
                 if (ival2 >= 0) {
                    sbit(cpack,&ival2,iofst,nbitsd);
                    iofst=iofst+nbitsd;
                 }
                 else {
                    sbit(cpack,&one,iofst,1);
                    iofst=iofst+1;
                    itemp=abs(ival2);
                    sbit(cpack,&itemp,iofst,nbitsd-1);
                    iofst=iofst+nbitsd-1;
                 }
              }
              //  pack overall min of spatial differences
              if (minsd >= 0) {
                 sbit(cpack,&minsd,iofst,nbitsd);
                 iofst=iofst+nbitsd;
              }
              else {
                 sbit(cpack,&one,iofst,1);
                 iofst=iofst+1;
                 itemp=abs(minsd);
                 sbit(cpack,&itemp,iofst,nbitsd-1);
                 iofst=iofst+nbitsd-1;
              }
           }
           //printf("SDp %ld %ld %ld %ld\n",ival1,ival2,minsd,nbitsd);
        }     //  end of spatial diff section
        //
        //   Determine Groups to be used.
        //
        if ( simple_alg == 1 ) {
           //  set group length to 10;  calculate number of groups
           //  and length of last group
           ngroups=ndpts/10;
           for (j=0;j<ngroups;j++) glen[j]=10;
           itemp=ndpts%10;
           if (itemp != 0) {
              ngroups=ngroups+1;
              glen[ngroups-1]=itemp;
           }
        }
        else {
           // Use Dr. Glahn's algorithm for determining grouping.
           //
           kfildo=6;
           minpk=10;
           inc=1;
           maxgrps=(ndpts/minpk)+1;
           jmin = calloc(maxgrps,sizeof(g2int));
           jmax = calloc(maxgrps,sizeof(g2int));
           lbit = calloc(maxgrps,sizeof(g2int));
           missopt=0;
           pack_gp(&kfildo,ifld,&ndpts,&missopt,&minpk,&inc,&miss1,&miss2,
                        jmin,jmax,lbit,glen,&maxgrps,&ngroups,&ibit,&jbit,
                        &kbit,&novref,&lbitref,&ier);
           //print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref
           for ( ng=0; ng<ngroups; ng++) glen[ng]=glen[ng]+novref;
           free(jmin);
           free(jmax);
           free(lbit);
        }
        //  
        //  For each group, find the group's reference value
        //  and the number of bits needed to hold the remaining values
        //
        n=0;
        for (ng=0;ng<ngroups;ng++) {
           //    find max and min values of group
           gref[ng]=ifld[n];
           imax=ifld[n];
           j=n+1;
           for (lg=1;lg<glen[ng];lg++) {
              if (ifld[j] < gref[ng]) gref[ng]=ifld[j]; 
              if (ifld[j] > imax) imax=ifld[j];
              j++;
           }
           //   calc num of bits needed to hold data
           if ( gref[ng] != imax ) {
              temp=(float)(log((double)(imax-gref[ng]+1))/alog2);
              gwidth[ng]=(g2int)ceil(temp);
           }
           else 
              gwidth[ng]=0;
           //   Subtract min from data
           j=n;
           for (lg=0;lg<glen[ng];lg++) {
              ifld[j]=ifld[j]-gref[ng];
              j++;
           }
           //   increment fld array counter
           n=n+glen[ng];
        }
        //  
        //  Find max of the group references and calc num of bits needed 
        //  to pack each groups reference value, then
        //  pack up group reference values
        //
        igmax=gref[0];
        for (j=1;j<ngroups;j++) if (gref[j] > igmax) igmax=gref[j];
        if (igmax != 0) {
           temp=(float)(log((double)(igmax+1))/alog2);
           nbitsgref=(g2int)ceil(temp);
           sbits(cpack,gref,iofst,nbitsgref,0,ngroups);
           itemp=nbitsgref*ngroups;
           iofst=iofst+itemp;
           //         Pad last octet with Zeros, if necessary,
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else
           nbitsgref=0;
        //
        //  Find max/min of the group widths and calc num of bits needed
        //  to pack each groups width value, then
        //  pack up group width values
        //
        iwmax=gwidth[0];
        ngwidthref=gwidth[0];
        for (j=1;j<ngroups;j++) {
           if (gwidth[j] > iwmax) iwmax=gwidth[j];
           if (gwidth[j] < ngwidthref) ngwidthref=gwidth[j];
        }
        if (iwmax != ngwidthref) {
           temp=(float)(log((double)(iwmax-ngwidthref+1))/alog2);
           nbitsgwidth=(g2int)ceil(temp);
           for (i=0;i<ngroups;i++) 
              gwidth[i]=gwidth[i]-ngwidthref;
           sbits(cpack,gwidth,iofst,nbitsgwidth,0,ngroups);
           itemp=nbitsgwidth*ngroups;
           iofst=iofst+itemp;
           //         Pad last octet with Zeros, if necessary,
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else {
           nbitsgwidth=0;
           for (i=0;i<ngroups;i++) gwidth[i]=0;
        }
        //
        //  Find max/min of the group lengths and calc num of bits needed
        //  to pack each groups length value, then
        //  pack up group length values
        //
        //write(77,*)'GLENS: ',(glen(j),j=1,ngroups)
        ilmax=glen[0];
        nglenref=glen[0];
        for (j=1;j<ngroups-1;j++) {
           if (glen[j] > ilmax) ilmax=glen[j];
           if (glen[j] < nglenref) nglenref=glen[j];
        }
        nglenlast=glen[ngroups-1];
        if (ilmax != nglenref) {
           temp=(float)(log((double)(ilmax-nglenref+1))/alog2);
           nbitsglen=(g2int)ceil(temp);
           for (i=0;i<ngroups-1;i++)  glen[i]=glen[i]-nglenref;
           sbits(cpack,glen,iofst,nbitsglen,0,ngroups);
           itemp=nbitsglen*ngroups;
           iofst=iofst+itemp;
           //         Pad last octet with Zeros, if necessary,
           if ( (itemp%8) != 0) {
              left=8-(itemp%8);
              sbit(cpack,&zero,iofst,left);
              iofst=iofst+left;
           }
        }
        else {
           nbitsglen=0;
           for (i=0;i<ngroups;i++) glen[i]=0;
        }
        //
        //  For each group, pack data values
        //
        n=0;
        for (ng=0;ng<ngroups;ng++) {
           glength=glen[ng]+nglenref;
           if (ng == (ngroups-1) ) glength=nglenlast;
           grpwidth=gwidth[ng]+ngwidthref;
           if ( grpwidth != 0 ) {
              sbits(cpack,ifld+n,iofst,grpwidth,0,glength);
              iofst=iofst+(grpwidth*glength);
           }
           n=n+glength;
        }
        //         Pad last octet with Zeros, if necessary,
        if ( (iofst%8) != 0) {
           left=8-(iofst%8);
           sbit(cpack,&zero,iofst,left);
           iofst=iofst+left;
        }
        *lcpack=iofst/8;
        //
        if ( ifld!=0 ) free(ifld);
        if ( gref!=0 ) free(gref);
        if ( gwidth!=0 ) free(gwidth);
        if ( glen!=0 ) free(glen);
      }
      else {          //   Constant field ( max = min )
        /* nbits=0; */
        *lcpack=0;
        nbitsgref=0;
        ngroups=0;
      }

//
//  Fill in ref value and number of bits in Template 5.2
//
      mkieee(&rmin,idrstmpl+0,1);   // ensure reference value is IEEE format
      idrstmpl[3]=nbitsgref;
      idrstmpl[4]=0;         // original data were reals
      idrstmpl[5]=1;         // general group splitting
      idrstmpl[6]=0;         // No internal missing values
      idrstmpl[7]=0;         // Primary missing value
      idrstmpl[8]=0;         // secondary missing value
      idrstmpl[9]=ngroups;          // Number of groups
      idrstmpl[10]=ngwidthref;       // reference for group widths
      idrstmpl[11]=nbitsgwidth;      // num bits used for group widths
      idrstmpl[12]=nglenref;         // Reference for group lengths
      idrstmpl[13]=1;                // length increment for group lengths
      idrstmpl[14]=nglenlast;        // True length of last group
      idrstmpl[15]=nbitsglen;        // num bits used for group lengths
      if (idrsnum == 3) {
         idrstmpl[17]=nbitsd/8;      // num bits used for extra spatial
                                     // differencing values
      }

}
예제 #9
0
파일: simpack.c 프로젝트: ryandavid/rotobox
void simpack(g2float *fld,g2int ndpts,g2int *idrstmpl,unsigned char *cpack,g2int *lcpack)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    simpack
//   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2002-11-06
//
// ABSTRACT: This subroutine packs up a data field using the simple
//   packing algorithm as defined in the GRIB2 documentation.  It
//   also fills in GRIB2 Data Representation Template 5.0 with the
//   appropriate values.
//
// PROGRAM HISTORY LOG:
// 2002-11-06  Gilbert
//
// USAGE:    CALL simpack(fld,ndpts,idrstmpl,cpack,lcpack)
//   INPUT ARGUMENT LIST:
//     fld[]    - Contains the data values to pack
//     ndpts    - The number of data values in array fld[]
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.0
//                [0] = Reference value - ignored on input
//                [1] = Binary Scale Factor
//                [2] = Decimal Scale Factor
//                [3] = Number of bits used to pack data, if value is
//                      > 0 and  <= 31.
//                      If this input value is 0 or outside above range
//                      then the num of bits is calculated based on given 
//                      data and scale factors.
//                [4] = Original field type - currently ignored on input
//                      Data values assumed to be reals.
//
//   OUTPUT ARGUMENT LIST: 
//     idrstmpl - Contains the array of values for Data Representation
//                Template 5.0
//                [0] = Reference value - set by simpack routine.
//                [1] = Binary Scale Factor - unchanged from input
//                [2] = Decimal Scale Factor - unchanged from input
//                [3] = Number of bits used to pack data, unchanged from 
//                      input if value is between 0 and 31.
//                      If this input value is 0 or outside above range
//                      then the num of bits is calculated based on given 
//                      data and scale factors.
//                [4] = Original field type - currently set = 0 on output.
//                      Data values assumed to be reals.
//     cpack    - The packed data field
//     lcpack   - length of packed field starting at cpack.
//
// REMARKS: None
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$
{

      const g2int zero=0;
      g2int  *ifld;
      g2int  j,nbits,imin,imax,maxdif,nbittot,left;
      g2float  bscale,dscale,rmax,rmin,temp;
      double maxnum;
      const g2float alog2=0.69314718f;       //  ln(2.0)
      
      bscale=(float)int_power(2.0,-idrstmpl[1]);
      dscale=(float)int_power(10.0,idrstmpl[2]);
      if (idrstmpl[3] <= 0 || idrstmpl[3] > 31)
         nbits=0;
      else
         nbits=idrstmpl[3];
//
//  Find max and min values in the data
//
      rmax=fld[0];
      rmin=fld[0];
      for (j=1;j<ndpts;j++) {
        if (fld[j] > rmax) rmax=fld[j];
        if (fld[j] < rmin) rmin=fld[j];
      }
     
      ifld=calloc(ndpts,sizeof(g2int));
//
//  If max and min values are not equal, pack up field.
//  If they are equal, we have a constant field, and the reference
//  value (rmin) is the value for each point in the field and
//  set nbits to 0.
//
      if (rmin != rmax) {
        //
        //  Determine which algorithm to use based on user-supplied 
        //  binary scale factor and number of bits.
        //
        if (nbits==0 && idrstmpl[1]==0) {
           //
           //  No binary scaling and calculate minimum number of 
           //  bits in which the data will fit.
           //
           imin=(g2int)RINT(rmin*dscale);
           imax=(g2int)RINT(rmax*dscale);
           maxdif=imax-imin;
           temp=(float)(log((double)(maxdif+1))/alog2);
           nbits=(g2int)ceil(temp);
           rmin=(g2float)imin;
           //   scale data
           for(j=0;j<ndpts;j++)
             ifld[j]=(g2int)RINT(fld[j]*dscale)-imin;
        }
        else if (nbits!=0 && idrstmpl[1]==0) {
           //
           //  Use minimum number of bits specified by user and
           //  adjust binary scaling factor to accommodate data.
           //
           rmin=rmin*dscale;
           rmax=rmax*dscale;
           maxnum=int_power(2.0,nbits)-1;
           temp=(float)(log(maxnum/(rmax-rmin))/alog2);
           idrstmpl[1]=(g2int)ceil(-1.0*temp);
           bscale=(float)int_power(2.0,-idrstmpl[1]);
           //   scale data
           for (j=0;j<ndpts;j++)
             ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin)*bscale);
        }
        else if (nbits==0 && idrstmpl[1]!=0) {
           //
           //  Use binary scaling factor and calculate minimum number of 
           //  bits in which the data will fit.
           //
           rmin=rmin*dscale;
           rmax=rmax*dscale;
           maxdif=(g2int)RINT((rmax-rmin)*bscale);
           temp=(float)(log((double)(maxdif+1))/alog2);
           nbits=(g2int)ceil(temp);
           //   scale data
           for (j=0;j<ndpts;j++)
             ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin)*bscale);
        }
        else if (nbits!=0 && idrstmpl[1]!=0) {
           //
           //  Use binary scaling factor and use minimum number of 
           //  bits specified by user.   Dangerous - may loose
           //  information if binary scale factor and nbits not set
           //  properly by user.
           //
           rmin=rmin*dscale;
           //   scale data
           for (j=0;j<ndpts;j++)
             ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin)*bscale);
        }
        //
        //  Pack data, Pad last octet with Zeros, if necessary,
        //  and calculate the length of the packed data in bytes
        //
        sbits(cpack,ifld+0,0,nbits,0,ndpts);
        nbittot=nbits*ndpts;
        left=8-(nbittot%8);
        if (left != 8) {
          sbit(cpack,&zero,nbittot,left);   // Pad with zeros to fill Octet
          nbittot=nbittot+left;
        }
        *lcpack=nbittot/8;
      }
      else {
        nbits=0;
        *lcpack=0;
      }

//
//  Fill in ref value and number of bits in Template 5.0
//
      //printf("SAGmkieee %f\n",rmin);
      mkieee(&rmin,idrstmpl+0,1);   // ensure reference value is IEEE format
      //printf("SAGmkieee %ld\n",idrstmpl[0]);
      idrstmpl[3]=nbits;
      idrstmpl[4]=0;         // original data were reals

      free(ifld);
}
예제 #10
0
파일: g2_addgrid.c 프로젝트: exit130/g2clib
g2int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl,g2int *ideflist,g2int idefnum)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_addgrid 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-01
//
// ABSTRACT: This routine packs up a Grid Definition Section (Section 3) 
//   and adds it to a GRIB2 message.  It is used with routines "g2_create",
//   "g2_addlocal", "g2_addfield",
//   and "g2_gribend" to create a complete GRIB2 message.
//   g2_create must be called first to initialize a new GRIB2 message.
//
// PROGRAM HISTORY LOG:
// 2002-11-01  Gilbert
// 2009-01-14  Vuong     Changed structure name template to gtemplate
//
// USAGE:    int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl,
//                          g2int *ideflist,g2int idefnum)
//   INPUT ARGUMENTS:
//     cgrib    - Char array that contains the GRIB2 message to which
//                section should be added.
//     igds     - Contains information needed for GRIB Grid Definition Section 3
//                Must be dimensioned >= 5.
//                igds[0]=Source of grid definition (see Code Table 3.0)
//                igds[1]=Number of grid points in the defined grid.
//                igds[2]=Number of octets needed for each 
//                            additional grid points definition.  
//                            Used to define number of
//                            points in each row ( or column ) for
//                            non-regular grids.  
//                            = 0, if using regular grid.
//                igds[3]=Interpretation of list for optional points 
//                            definition.  (Code Table 3.11)
//                igds[4]=Grid Definition Template Number (Code Table 3.1)
//     igdstmpl - Contains the data values for the specified Grid Definition
//                Template ( NN=igds[4] ).  Each element of this integer 
//                array contains an entry (in the order specified) of Grid
//                Defintion Template 3.NN
//     ideflist - (Used if igds[2] != 0)  This array contains the
//                number of grid points contained in each row ( or column )
//      idefnum - (Used if igds[2] != 0)  The number of entries
//                in array ideflist.  i.e. number of rows ( or columns )
//                for which optional grid points are defined.
//
//   OUTPUT ARGUMENTS:      
//     cgrib    - Char array to contain the updated GRIB2 message.
//                Must be allocated large enough to store the entire
//                GRIB2 message.
//
//   RETURN VALUES:
//     ierr     - Return code.
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.  Need to call
//                    routine gribcreate first.
//               -2 = GRIB message already complete.  Cannot add new section.
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 1, 2 or 7.
//               -5 = Could not find requested Grid Definition Template.
//
// REMARKS: Note that the Grid Def Section ( Section 3 ) can only follow
//          Section 1, 2 or Section 7 in a GRIB2 message.
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$
{

      g2int ierr;
      static unsigned char G=0x47;       // 'G'
      static unsigned char R=0x52;       // 'R'
      static unsigned char I=0x49;       // 'I'
      static unsigned char B=0x42;       // 'B'
      static unsigned char seven=0x37;   // '7'

      static g2int one=1,three=3,miss=65535;
      g2int   lensec3,iofst,ibeg,lencurr,len;
      g2int   i,j,temp,ilen,isecnum,nbits;
      gtemplate *mapgrid=0;
 
      ierr=0;
//
//  Check to see if beginning of GRIB message exists
//
      if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
        // printf("g2_addgrid: GRIB not found in given message.\n");
        // printf("g2_addgrid: Call to routine gribcreate required to initialize GRIB messge.\n");
        ierr=-1;
        return(ierr);
      }
//
//  Get current length of GRIB message
//  
      gbit(cgrib,&lencurr,96,32);
//
//  Check to see if GRIB message is already complete
//  
      if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven &&
           cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) {
        // printf("g2_addgrid: GRIB message already complete.  Cannot add new section.\n");
        ierr=-2;
        return(ierr);
      }
//
//  Loop through all current sections of the GRIB message to
//  find the last section number.
//
      len=16;    // length of Section 0
      for (;;) { 
      //    Get section number and length of next section
        iofst=len*8;
        gbit(cgrib,&ilen,iofst,32);
        iofst=iofst+32;
        gbit(cgrib,&isecnum,iofst,8);
        len=len+ilen;
      //    Exit loop if last section reached
        if ( len == lencurr ) break;
      //    If byte count for each section doesn't match current
      //    total length, then there is a problem.
        if ( len > lencurr ) {
          // printf("g2_addgrid: Section byte counts don''t add to total.\n");
          // printf("g2_addgrid: Sum of section byte counts = %ld\n",len);
          // printf("g2_addgrid: Total byte count in Section 0 = %ld\n",lencurr);
          ierr=-3;
          return(ierr);
        }
      }
//
//  Section 3 can only be added after sections 1, 2 and 7.
//
      if ( (isecnum!=1) && (isecnum!=2) && (isecnum!=7) ) {
        // printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n");
        // printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n");
        ierr=-4;
        return(ierr);
      }
//
//  Add Section 3  - Grid Definition Section
//
      ibeg=lencurr*8;        //   Calculate offset for beginning of section 3
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&three,iofst,8);     // Store section number ( 3 )
      iofst=iofst+8;
      sbit(cgrib,igds+0,iofst,8);     // Store source of Grid def.
      iofst=iofst+8;
      sbit(cgrib,igds+1,iofst,32);    // Store number of data pts.
      iofst=iofst+32;
      sbit(cgrib,igds+2,iofst,8);     // Store number of extra octets.
      iofst=iofst+8;
      sbit(cgrib,igds+3,iofst,8);     // Store interp. of extra octets.
      iofst=iofst+8;
      //   if Octet 6 is not equal to zero, Grid Definition Template may
      //   not be supplied.
      if ( igds[0] == 0 )
        sbit(cgrib,igds+4,iofst,16);  // Store Grid Def Template num.
      else
        sbit(cgrib,&miss,iofst,16);   // Store missing value as Grid Def Template num.
      iofst=iofst+16;
      //
      //   Get Grid Definition Template
      //
      if (igds[0] == 0) {
        mapgrid=getgridtemplate(igds[4]);
        if (mapgrid == 0) {       // undefined template
          ierr=-5;
          return(ierr);
        }
        //
        //   Extend the Grid Definition Template, if necessary.
        //   The number of values in a specific template may vary
        //   depending on data specified in the "static" part of the
        //   template.
        //
        if ( mapgrid->needext ) {
          free(mapgrid);
          mapgrid=extgridtemplate(igds[4],igdstmpl);
        }
      }
      //
      //   Pack up each input value in array igdstmpl into the
      //   the appropriate number of octets, which are specified in
      //   corresponding entries in array mapgrid.
      //
      for (i=0;i<mapgrid->maplen;i++) {
        nbits=abs(mapgrid->map[i])*8;
        if ( (mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0) )
          sbit(cgrib,igdstmpl+i,iofst,nbits);
        else {
          sbit(cgrib,&one,iofst,1);
          temp=abs(igdstmpl[i]);
          sbit(cgrib,&temp,iofst+1,nbits-1);
        }
        iofst=iofst+nbits;
      }
      //  Pack template extension, if appropriate
      j=mapgrid->maplen;
      if ( mapgrid->needext && (mapgrid->extlen > 0) ) {
         for (i=0;i<mapgrid->extlen;i++) {
           nbits=abs(mapgrid->ext[i])*8;
           if ( (mapgrid->ext[i] >= 0) || (igdstmpl[j] >= 0) )
             sbit(cgrib,igdstmpl+j,iofst,nbits);
           else {
             sbit(cgrib,&one,iofst,1);
             temp=abs(igdstmpl[j]);
             sbit(cgrib,&temp,iofst+1,nbits-1);
           }
           iofst=iofst+nbits;
           j++;
         }
      }
      free(mapgrid);
      //
      //   If requested,
      //   Insert optional list of numbers defining number of points
      //   in each row or column.  This is used for non regular
      //   grids.
      //
      if ( igds[2] != 0 ) {
         nbits=igds[2]*8;
         sbits(cgrib,ideflist,iofst,nbits,0,idefnum);
         iofst=iofst+(nbits*idefnum);
      }
      //
      //   Calculate length of section 3 and store it in octets
      //   1-4 of section 3.
      //
      lensec3=(iofst-ibeg)/8;
      sbit(cgrib,&lensec3,ibeg,32);

//
//  Update current byte total of message in Section 0
//
      lencurr+=lensec3;
      sbit(cgrib,&lencurr,96,32);

      return(lencurr);

}
예제 #11
0
파일: g2_create.c 프로젝트: Mavrx-inc/gdal
g2int g2_create(unsigned char *cgrib,g2int *listsec0,g2int *listsec1)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_create
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
//
// ABSTRACT: This routine initializes a new GRIB2 message and packs
//   GRIB2 sections 0 (Indicator Section) and 1 (Identification Section).
//   This routine is used with routines "g2_addlocal", "g2_addgrid",
//   "g2_addfield", and "g2_gribend" to create a complete GRIB2 message.
//   g2_create must be called first to initialize a new GRIB2 message.
//   Also, a call to g2_gribend is required to complete GRIB2 message
//   after all fields have been added.
//
// PROGRAM HISTORY LOG:
// 2002-10-31  Gilbert
//
// USAGE:    int g2_create(unsigned char *cgrib,g2int *listsec0,g2int *listsec1)
//   INPUT ARGUMENTS:
//     cgrib    - Character array to contain the GRIB2 message
//     listsec0 - Contains information needed for GRIB Indicator Section 0.
//                Must be dimensioned >= 2.
//                listsec0[0]=Discipline-GRIB Master Table Number
//                            (see Code Table 0.0)
//                listsec0[1]=GRIB Edition Number (currently 2)
//     listsec1 - Contains information needed for GRIB Identification Section 1.
//                Must be dimensioned >= 13.
//                listsec1[0]=Id of originating centre (Common Code Table C-1)
//                listsec1[1]=Id of originating sub-centre (local table)
//                listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0)
//                listsec1[3]=GRIB Local Tables Version Number (Code Table 1.1)
//                listsec1[4]=Significance of Reference Time (Code Table 1.2)
//                listsec1[5]=Reference Time - Year (4 digits)
//                listsec1[6]=Reference Time - Month
//                listsec1[7]=Reference Time - Day
//                listsec1[8]=Reference Time - Hour
//                listsec1[9]=Reference Time - Minute
//                listsec1[10]=Reference Time - Second
//                listsec1[11]=Production status of data (Code Table 1.3)
//                listsec1[12]=Type of processed data (Code Table 1.4)
//
//   OUTPUT ARGUMENTS:
//     cgrib    - Char array to contain the new GRIB2 message.
//                Must be allocated large enough to store the entire
//                GRIB2 message.
//
//   RETURN VALUES:
//     ierr     - return code.
//              > 0 = Current size of new GRIB2 message
//               -1 = Tried to use for version other than GRIB Edition 2
//
// REMARKS: This routine is intended for use with routines "g2_addlocal",
//          "g2_addgrid", "g2_addfield", and "g2_gribend" to create a complete
//          GRIB2 message.
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$
{

      g2int   zero=0,one=1;
      g2int   mapsec1len=MAPSEC1LEN;
      g2int   mapsec1[MAPSEC1LEN]={ 2,2,1,1,1,2,1,1,1,1,1,1,1 };
      g2int   i,lensec0,lensec1,iofst,ibeg,nbits,len;

//
//  Currently handles only GRIB Edition 2.
//
      if (listsec0[1] != 2) {
        printf("g2_create: can only code GRIB edition 2.");
        return (-1);
      }
//
//  Pack Section 0 - Indicator Section
//  ( except for total length of GRIB message )
//
      cgrib[0]=0x47;   // 'G'            // Beginning of GRIB message
      cgrib[1]=0x52;   // 'R'
      cgrib[2]=0x49;   // 'I'
      cgrib[3]=0x42;   // 'B'
      sbit(cgrib,&zero,32,16);           // reserved for future use
      sbit(cgrib,listsec0+0,48,8);       // Discipline
      sbit(cgrib,listsec0+1,56,8);       // GRIB edition number
      lensec0=16;      // bytes (octets)
//
//  Pack Section 1 - Identification Section
//
      ibeg=lensec0*8;        //   Calculate offset for beginning of section 1
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&one,iofst,8);     // Store section number ( 1 )
      iofst=iofst+8;
      //
      //   Pack up each input value in array listsec1 into the
      //   the appropriate number of octets, which are specified in
      //   corresponding entries in array mapsec1.
      //
      for (i=0;i<mapsec1len;i++) {
        nbits=mapsec1[i]*8;
        sbit(cgrib,listsec1+i,iofst,nbits);
        iofst=iofst+nbits;
      }
      //
      //   Calculate length of section 1 and store it in octets
      //   1-4 of section 1.
      //
      lensec1=(iofst-ibeg)/8;
      sbit(cgrib,&lensec1,ibeg,32);
//
//  Put current byte total of message into Section 0
//
      sbit(cgrib,&zero,64,32);
      len=lensec0+lensec1;
      sbit(cgrib,&len,96,32);

      return (len);

}
예제 #12
0
g2int g2_addfield(unsigned char *cgrib,g2int ipdsnum,g2int *ipdstmpl,
                g2float *coordlist,g2int numcoord,g2int idrsnum,g2int *idrstmpl,
                g2float *fld,g2int ngrdpts,g2int ibmap,g2int *bmap)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_addfield 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-05
//
// ABSTRACT: This routine packs up Sections 4 through 7 for a given field
//   and adds them to a GRIB2 message.  They are Product Definition Section,
//   Data Representation Section, Bit-Map Section and Data Section, 
//   respectively.
//   This routine is used with routines "g2_create", "g2_addlocal", 
//   "g2_addgrid", and "g2_gribend" to create a complete GRIB2 message.  
//   g2_create must be called first to initialize a new GRIB2 message.
//   Also, routine g2_addgrid must be called after g2_create and
//   before this routine to add the appropriate grid description to
//   the GRIB2 message.   Also, a call to g2_gribend is required to complete 
//   GRIB2 message after all fields have been added.
//
// PROGRAM HISTORY LOG:
// 2002-11-05  Gilbert
// 2002-12-23  Gilbert  -  Added complex spherical harmonic packing
// 2003-08-27  Gilbert  - Added support for new templates using
//                        PNG and JPEG2000 algorithms/templates.
// 2004-11-29  Gilbert  - JPEG2000 now allowed to use WMO Template no. 5.40
//                        PNG now allowed to use WMO Template no. 5.41
//                      - Added check to determine if packing algorithm failed.
// 2005-05-10  Gilbert -  Imposed minimum size on cpack, used to hold encoded
//                        bit string.
//
// USAGE:    int g2_addfield(unsigned char *cgrib,g2int ipdsnum,g2int *ipdstmpl,
//              g2float *coordlist,g2int numcoord,g2int idrsnum,g2int *idrstmpl,
//              g2float *fld,g2int ngrdpts,g2int ibmap,g2int *bmap)
//   INPUT ARGUMENT LIST:
//     cgrib    - Char array that contains the GRIB2 message to which sections
//                4 through 7 should be added.
//     ipdsnum  - Product Definition Template Number ( see Code Table 4.0)
//     ipdstmpl - Contains the data values for the specified Product Definition
//                Template ( N=ipdsnum ).  Each element of this integer 
//                array contains an entry (in the order specified) of Product
//                Defintion Template 4.N
//     coordlist- Array containg floating point values intended to document
//                the vertical discretisation associated to model data
//                on hybrid coordinate vertical levels.
//     numcoord - number of values in array coordlist.
//     idrsnum  - Data Representation Template Number ( see Code Table 5.0 )
//     idrstmpl - Contains the data values for the specified Data Representation
//                Template ( N=idrsnum ).  Each element of this integer 
//                array contains an entry (in the order specified) of Data
//                Representation Template 5.N
//                Note that some values in this template (eg. reference
//                values, number of bits, etc...) may be changed by the
//                data packing algorithms.
//                Use this to specify scaling factors and order of
//                spatial differencing, if desired.
//     fld[]    - Array of data points to pack.
//     ngrdpts  - Number of data points in grid.
//                i.e.  size of fld and bmap.
//     ibmap    - Bitmap indicator ( see Code Table 6.0 )
//                0 = bitmap applies and is included in Section 6.
//                1-253 = Predefined bitmap applies
//                254 = Previously defined bitmap applies to this field
//                255 = Bit map does not apply to this product.
//     bmap[]   - Integer array containing bitmap to be added. ( if ibmap=0 )
//
//   OUTPUT ARGUMENT LIST:      
//     cgrib    - Character array to contain the updated GRIB2 message.
//                Must be allocated large enough to store the entire
//                GRIB2 message.
//
//   RETURN VALUES:
//     ierr     - Return code.
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.  Need to call
//                    routine g2_create first.
//               -2 = GRIB message already complete.  Cannot add new section.
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 3 or 7.
//               -5 = Could not find requested Product Definition Template.
//               -6 = Section 3 (GDS) not previously defined in message
//               -7 = Tried to use unsupported Data Representationi Template
//               -8 = Specified use of a previously defined bitmap, but one
//                    does not exist in the GRIB message.
//               -9 = GDT of one of 5.50 through 5.53 required to pack field
//                    using DRT 5.51.
//              -10 = Error packing data field.
//
// REMARKS: Note that the Sections 4 through 7 can only follow
//          Section 3 or Section 7 in a GRIB2 message.
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$
{
      g2int ierr;
      static unsigned char G=0x47;       // 'G'
      static unsigned char R=0x52;       // 'R'
      static unsigned char I=0x49;       // 'I'
      static unsigned char B=0x42;       // 'B'
      static unsigned char s7=0x37;   // '7'

      unsigned char *cpack;
      static g2int  zero=0,one=1,four=4,five=5,six=6,seven=7;
      const g2int  minsize=50000;
      g2int   iofst,ibeg,lencurr,len,nsize;
      g2int   ilen,isecnum,i,nbits,temp,left;
      g2int   ibmprev,j,lcpack,ioctet,newlen,ndpts;
      g2int   lensec4,lensec5,lensec6,lensec7;
      g2int   issec3,isprevbmap,lpos3=0,JJ,KK,MM;
      g2int   *coordieee;
      g2int   width,height,iscan,itemp;
      g2float *pfld;
      xxtemplate  *mappds,*mapdrs;
      unsigned int allones=4294967295u;
 
      ierr=0;
//
//  Check to see if beginning of GRIB message exists
//
      if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
        printf("g2_addfield: GRIB not found in given message.\n");
        printf("g2_addfield: Call to routine g2_create required to initialize GRIB messge.\n");
        ierr=-1;
        return(ierr);
      }
//
//  Get current length of GRIB message
//  
      gbit(cgrib,&lencurr,96,32);
//
//  Check to see if GRIB message is already complete
//  
      if ( cgrib[lencurr-4]==s7 && cgrib[lencurr-3]==s7 &&
           cgrib[lencurr-2]==s7 && cgrib[lencurr-1]==s7 ) {
        printf("g2_addfield: GRIB message already complete.  Cannot add new section.\n");
        ierr=-2;
        return(ierr);
      }
//
//  Loop through all current sections of the GRIB message to
//  find the last section number.
//
      issec3=0;
      isprevbmap=0;
      len=16;    // length of Section 0
      for (;;) { 
      //    Get number and length of next section
        iofst=len*8;
        gbit(cgrib,&ilen,iofst,32);
        iofst=iofst+32;
        gbit(cgrib,&isecnum,iofst,8);
        iofst=iofst+8;
      //  Check if previous Section 3 exists
        if (isecnum == 3) {
            issec3=1;
            lpos3=len;
        }
      //  Check if a previous defined bitmap exists
        if (isecnum == 6) {
          gbit(cgrib,&ibmprev,iofst,8);
          iofst=iofst+8;
          if ((ibmprev >= 0) && (ibmprev <= 253)) isprevbmap=1;
        }
        len=len+ilen;
      //    Exit loop if last section reached
        if ( len == lencurr ) break;
      //    If byte count for each section doesn't match current
      //    total length, then there is a problem.
        if ( len > lencurr ) {
          printf("g2_addfield: Section byte counts don''t add to total.\n");
          printf("g2_addfield: Sum of section byte counts = %d\n",len);
          printf("g2_addfield: Total byte count in Section 0 = %d\n",lencurr);
          ierr=-3;
          return(ierr);
        }
      }
//
//  Sections 4 through 7 can only be added after section 3 or 7.
//
      if ( (isecnum != 3) && (isecnum != 7) ) {
        printf("g2_addfield: Sections 4-7 can only be added after Section 3 or 7.\n");
        printf("g2_addfield: Section ',isecnum,' was the last found in given GRIB message.\n");
        ierr=-4;
        return(ierr);
//
//  Sections 4 through 7 can only be added if section 3 was previously defined.
//
      }
      else if ( ! issec3) {
        printf("g2_addfield: Sections 4-7 can only be added if Section 3 was previously included.\n");
        printf("g2_addfield: Section 3 was not found in given GRIB message.\n");
        printf("g2_addfield: Call to routine addgrid required to specify Grid definition.\n");
        ierr=-6;
        return(ierr);
      }
//
//  Add Section 4  - Product Definition Section
//
      ibeg=lencurr*8;        //   Calculate offset for beginning of section 4
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&four,iofst,8);     // Store section number ( 4 )
      iofst=iofst+8;
      sbit(cgrib,&numcoord,iofst,16);   // Store num of coordinate values
      iofst=iofst+16;
      sbit(cgrib,&ipdsnum,iofst,16);    // Store Prod Def Template num.
      iofst=iofst+16;
      //
      //   Get Product Definition Template
      //
      mappds=getpdstemplate(ipdsnum);
      if (mappds == 0) {          // undefined template
        ierr=-5;
        return(ierr);
      }
      //
      //   Extend the Product Definition Template, if necessary.
      //   The number of values in a specific template may vary
      //   depending on data specified in the "static" part of the
      //   template.
      //
      if ( mappds->needext ) {
        free(mappds);
        mappds=extpdstemplate(ipdsnum,ipdstmpl);
      }
      //
      //   Pack up each input value in array ipdstmpl into the
      //   the appropriate number of octets, which are specified in
      //   corresponding entries in array mappds.
      //
      for (i=0;i<mappds->maplen;i++) {
        nbits=abs(mappds->map[i])*8;
        if ( (mappds->map[i] >= 0) || (ipdstmpl[i] >= 0) )
          sbit(cgrib,ipdstmpl+i,iofst,nbits);
        else {
          sbit(cgrib,&one,iofst,1);
          temp=abs(ipdstmpl[i]);
          sbit(cgrib,&temp,iofst+1,nbits-1);
        }
        iofst=iofst+nbits;
      }
      //  Pack template extension, if appropriate
      j=mappds->maplen;
      if ( mappds->needext && (mappds->extlen > 0) ) {
         for (i=0;i<mappds->extlen;i++) {
           nbits=abs(mappds->ext[i])*8;
           if ( (mappds->ext[i] >= 0) || (ipdstmpl[j] >= 0) )
             sbit(cgrib,ipdstmpl+j,iofst,nbits);
           else {
             sbit(cgrib,&one,iofst,1);
             temp=abs(ipdstmpl[j]);
             sbit(cgrib,&temp,iofst+1,nbits-1);
           }
           iofst=iofst+nbits;
           j++;
         }
      }
      free(mappds);
      //
      //   Add Optional list of vertical coordinate values
      //   after the Product Definition Template, if necessary.
      //
      if ( numcoord != 0 ) {
        coordieee=(g2int *)calloc(numcoord,sizeof(g2int));
        mkieee(coordlist,coordieee,numcoord);
        sbits(cgrib,coordieee,iofst,32,0,numcoord);
        iofst=iofst+(32*numcoord);
        free(coordieee);
      }
      //
      //   Calculate length of section 4 and store it in octets
      //   1-4 of section 4.
      //
      lensec4=(iofst-ibeg)/8;
      sbit(cgrib,&lensec4,ibeg,32);
//
//  Pack Data using appropriate algorithm
//
      //
      //   Get Data Representation Template
      //
      mapdrs=getdrstemplate(idrsnum);
      if (mapdrs == 0) {
        ierr=-5;
        return(ierr);
      }
      //
      //  contract data field, removing data at invalid grid points,
      //  if bit-map is provided with field.
      //
      if ( ibmap == 0 || ibmap==254 ) {
         pfld=(g2float *)malloc(ngrdpts*sizeof(g2float));
         ndpts=0;
         for (j=0;j<ngrdpts;j++) {
             if ( bmap[j]==1 ) pfld[ndpts++]=fld[j];
         }
      }
      else {
         ndpts=ngrdpts;
         pfld=fld;
      }
      nsize=ndpts*4;
      if ( nsize < minsize ) nsize=minsize;
      cpack=malloc(nsize);
      if (idrsnum == 0)           //  Simple Packing
        simpack(pfld,ndpts,idrstmpl,cpack,&lcpack);
      else if (idrsnum==2 || idrsnum==3)           //  Complex Packing
        cmplxpack(pfld,ndpts,idrsnum,idrstmpl,cpack,&lcpack);
      else if (idrsnum == 50) {         //  Sperical Harmonic Simple Packing 
        simpack(pfld+1,ndpts-1,idrstmpl,cpack,&lcpack);
        mkieee(pfld+0,idrstmpl+4,1);  // ensure RE(0,0) value is IEEE format
      }
      else if (idrsnum == 51) {         //  Sperical Harmonic Complex Packing 
        getpoly(cgrib+lpos3,&JJ,&KK,&MM);
        if ( JJ!=0 && KK!=0 && MM!=0 )
           specpack(pfld,ndpts,JJ,KK,MM,idrstmpl,cpack,&lcpack);
        else {
           printf("g2_addfield: Cannot pack DRT 5.51.\n");
           return (-9);
        }
      }
      else if (idrsnum == 40 || idrsnum == 40000) {    /*  JPEG2000 encoding  */
        if (ibmap == 255) {
           getdim(cgrib+lpos3,&width,&height,&iscan);
           if ( width==0 || height==0 ) {
              width=ndpts;
              height=1;
           }
           else if ( width==allones || height==allones ) {
              width=ndpts;
              height=1;
           }
           else if ( (iscan&32) == 32) {   /* Scanning mode: bit 3  */
              itemp=width;
              width=height;
              height=itemp;
           }
        }
        else {
           width=ndpts;
           height=1;
        }
        lcpack=nsize;
        jpcpack(pfld,width,height,idrstmpl,cpack,&lcpack);
      }
#ifdef USE_PNG
      else if (idrsnum == 41 || idrsnum == 40010) {      /*  PNG encoding   */
        if (ibmap == 255) {
           getdim(cgrib+lpos3,&width,&height,&iscan);
           if ( width==0 || height==0 ) {
              width=ndpts;
              height=1;
           }
           else if ( width==allones || height==allones ) {
              width=ndpts;
              height=1;
           }
           else if ( (iscan&32) == 32) {   /* Scanning mode: bit 3  */
              itemp=width;
              width=height;
              height=itemp;
           }
        }
        else {
           width=ndpts;
           height=1;
        }
        pngpack(pfld,width,height,idrstmpl,cpack,&lcpack);
      }
#endif  /* USE_PNG */
      else {
        printf("g2_addfield: Data Representation Template 5.%d not yet implemented.\n",idrsnum);
        ierr=-7;
        return(ierr);
      }
      if ( ibmap == 0 || ibmap==254 ) {      // free temp space
         if (fld != pfld) free(pfld);
      }
      if ( lcpack < 0 ) {
        if( cpack != 0 ) free(cpack);
        ierr=-10;
        return(ierr);
      }

//
//  Add Section 5  - Data Representation Section
//
      ibeg=iofst;            //   Calculate offset for beginning of section 5
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&five,iofst,8);     // Store section number ( 5 )
      iofst=iofst+8;
      sbit(cgrib,&ndpts,iofst,32);    // Store num of actual data points
      iofst=iofst+32;
      sbit(cgrib,&idrsnum,iofst,16);    // Store Data Repr. Template num.
      iofst=iofst+16;
      //
      //   Pack up each input value in array idrstmpl into the
      //   the appropriate number of octets, which are specified in
      //   corresponding entries in array mapdrs.
      //
      for (i=0;i<mapdrs->maplen;i++) {
        nbits=abs(mapdrs->map[i])*8;
        if ( (mapdrs->map[i] >= 0) || (idrstmpl[i] >= 0) )
          sbit(cgrib,idrstmpl+i,iofst,nbits);
        else {
          sbit(cgrib,&one,iofst,1);
          temp=abs(idrstmpl[i]);
          sbit(cgrib,&temp,iofst+1,nbits-1);
        }
        iofst=iofst+nbits;
      }
      free(mapdrs);
      //
      //   Calculate length of section 5 and store it in octets
      //   1-4 of section 5.
      //
      lensec5=(iofst-ibeg)/8;
      sbit(cgrib,&lensec5,ibeg,32);

//
//  Add Section 6  - Bit-Map Section
//
      ibeg=iofst;            //   Calculate offset for beginning of section 6
      iofst=ibeg+32;         //   leave space for length of section
      sbit(cgrib,&six,iofst,8);     // Store section number ( 6 )
      iofst=iofst+8;
      sbit(cgrib,&ibmap,iofst,8);    // Store Bit Map indicator
      iofst=iofst+8;
      //
      //  Store bitmap, if supplied
      //
      if (ibmap == 0) {
        sbits(cgrib,bmap,iofst,1,0,ngrdpts);    // Store BitMap
        iofst=iofst+ngrdpts;
      }
      //
      //  If specifying a previously defined bit-map, make sure
      //  one already exists in the current GRIB message.
      //
      if ((ibmap==254) && ( ! isprevbmap)) {
        printf("g2_addfield: Requested previously defined bitmap,");
        printf(" but one does not exist in the current GRIB message.\n");
        ierr=-8;
        return(ierr);
      }
      //
      //   Calculate length of section 6 and store it in octets
      //   1-4 of section 6.  Pad to end of octect, if necessary.
      //
      left=8-(iofst%8);
      if (left != 8) {
        sbit(cgrib,&zero,iofst,left);     // Pad with zeros to fill Octet
        iofst=iofst+left;
      }
      lensec6=(iofst-ibeg)/8;
      sbit(cgrib,&lensec6,ibeg,32);

//
//  Add Section 7  - Data Section
//
      ibeg=iofst;            //   Calculate offset for beginning of section 7
      iofst=ibeg+32;        //   leave space for length of section
      sbit(cgrib,&seven,iofst,8);    // Store section number ( 7 )
      iofst=iofst+8;
      //      Store Packed Binary Data values, if non-constant field
      if (lcpack != 0) {
        ioctet=iofst/8;
        //cgrib(ioctet+1:ioctet+lcpack)=cpack(1:lcpack)
        for (j=0;j<lcpack;j++) cgrib[ioctet+j]=cpack[j];
        iofst=iofst+(8*lcpack);
      }
      //
      //   Calculate length of section 7 and store it in octets
      //   1-4 of section 7.  
      //
      lensec7=(iofst-ibeg)/8;
      sbit(cgrib,&lensec7,ibeg,32);

      if( cpack != 0 ) free(cpack);
//
//  Update current byte total of message in Section 0
//
      newlen=lencurr+lensec4+lensec5+lensec6+lensec7;
      sbit(cgrib,&newlen,96,32);

      return(newlen);

}
예제 #13
0
int main(void)
{
	// init hardware setup
	init();

	// setup temperature resolution
	// write temperature register pointer
	i2c_start(TEMPSENS_ADDRESS, I2C_WRITE);
	i2c_write(0x01);
	i2c_write(0b01100000);
	i2c_stop();

    while(1)
    {
		// change mode by pressed button
		if (button1Pressed())
		{
			mode = MODE_1;
		}
		else if (button2Pressed())
		{
			mode = MODE_2;
		}
		else if (button3Pressed())
		{
			mode = MODE_3;
		}

		// mode1
		if (mode == MODE_1)
		{
			// read analog value from potentiometer
			uint32_t pot = readAnalog(POT_CHANNEL);
			pot *= 4888;
			pot += 500;
			pot /= 1000;

			if (++mydelay >= 10)
			{
				writeDisplayNumber(pot, 0);
				mydelay = 0;
			}
			

			// led1 on
			sbit(OUTPORT(LED1_PORT), LED1_BIT);
		}
		else
		{
			// led1 off
			cbit(OUTPORT(LED1_PORT), LED1_BIT);			
		}

		// mode2
		if (mode == MODE_2)
		{

			int16_t temp = readTemperature();
			writeDisplayTemp(temp, 2);

			// led2 on
			sbit(OUTPORT(LED2_PORT), LED2_BIT);
		}
		else
		{
			// led2 off
			cbit(OUTPORT(LED2_PORT), LED2_BIT);
		}

		// show potentiometer value		
		if (mode == MODE_3)
		{
			// led3 on
			sbit(OUTPORT(LED3_PORT), LED3_BIT);
			
			mode3();
			
			/*
			if (mydelay < 12)
			{
				// turn-on buzzer
				// frequency 2kHz
				ICR1 = 2000;
				OCR1A = 1000;
				// write to display
				writeDisplayData(convertBcd(DIGIT_MINUS, DIGIT_MINUS, DIGIT_BLANK, DIGIT_BLANK, 255));
			}
			else
			{
				// turn-on buzzer
				// frequency 2kHz
				ICR1 = 4000;
				OCR1A = 2000;
				// write to display
				writeDisplayData(convertBcd(DIGIT_BLANK, DIGIT_BLANK, DIGIT_MINUS, DIGIT_MINUS, 255));			}
			if (++mydelay >= 25) mydelay = 0;
			*/
		}
		else
		{
			// turn-off buzzer
			ICR1 = 0;
			// led3 off
			cbit(OUTPORT(LED3_PORT), LED3_BIT);
		}


		// wait until all mode buttons are released
		while (button1Pressed() || button2Pressed() || button3Pressed());
		_delay_ms(20);
    }
}
예제 #14
0
void mode3()
{
	uint8_t t = 100;
	uint8_t esc[3] = {255, 255, 255};

	// wait for start
	writeDisplayNumber(t, 1);

	while (!button4Pressed());
	
	uint8_t swlast = 0;
	
	while (1)
	{
		t--;
		writeDisplayNumber(t, 1);
		
		if (button4Pressed() && swlast == 0)
		{
			swlast = 1;
			
			esc[2] = esc[1];
			esc[1] = esc[0];
			esc[0] = t;
			
			// deactivate
			if (esc[2] - esc[0] < 10) break;
		}
		else if (!button4Pressed() && swlast == 1)
		{
			swlast = 0;
		}
		
		
		uint8_t f = t % 10;
		
		OCR1A = 500;
		
		switch (f)
		{
			case 0:
				// turn-on buzzer
				ICR1 = 1000;				
				break;
			case 9:
				// turn-off buzzer
				ICR1 = 0;				
				break;

			case 5:
				if (t < 50 && t > 20)
				{
					ICR1 = 1000;
				}
				if (t < 20)
				{
					ICR1 = 0;
				}
				break;
			case 4:
				if (t < 50 && t > 20)
				{
					ICR1 = 0;
				}
				if (t < 20)
				{
					ICR1 = 1000;
				}
				break;
			case 8:
			case 6:
			case 2:
			if (t < 20)
			{
				ICR1 = 1000;
			}
			break;
			case 7:
			case 3:
			case 1:
			if (t < 20)
			{
				ICR1 = 0;
			}
			break;

		}
		
		if (t == 0) break;
		
		_delay_ms(100);
	}

	
	if (t == 0)
	{
		sbit(OUTPORT(LED4_PORT), LED4_BIT);
	}
	else
	{
		ICR1 = 0;
		
	}

	while (!button3Pressed());
	
}
예제 #15
0
// Setup MCU input/output
void init()
{
	// Display connection pins output
	sbit(DDR(DISP_DATA_PORT), DISP_DATA_BIT);
	sbit(DDR(DISP_CLK_PORT), DISP_CLK_BIT);
	sbit(DDR(DISP_LATCH_PORT), DISP_LATCH_BIT);
	sbit(DDR(DISP_OE_PORT), DISP_OE_BIT);

	// SPI configuration: master, sck=fclk/128=125kHz
	SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);

	// LEDs output
	sbit(DDR(LED1_PORT), LED1_BIT);
	sbit(DDR(LED2_PORT), LED2_BIT);
	sbit(DDR(LED3_PORT), LED3_BIT);
	sbit(DDR(LED4_PORT), LED4_BIT);
	
	// Button pull-ups
	sbit(OUTPORT(BUTTON1_PORT), BUTTON1_BIT);
	sbit(OUTPORT(BUTTON2_PORT), BUTTON2_BIT);
	sbit(OUTPORT(BUTTON3_PORT), BUTTON3_BIT);
	sbit(OUTPORT(BUTTON4_PORT), BUTTON4_BIT);
	
	// Buzzer timer output
	sbit(DDR(BUZZER_PORT), BUZZER_BIT);
	TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
	TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);
	ICR1 = 0;		// timer top value
	OCR1A = 500;	// output compare value

	// ADC initialization
	// - ADC clock frequency: F_CPU / 128 (125kHz @ 16MHz)
	// - reference: AVcc with external cap
	ADMUX = (1<<REFS0);
	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
	
	// init I2C interface
	i2c_init();
}