예제 #1
0
CPLErr AAIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                   void *pImage )

{
    AAIGDataset *poODS = static_cast<AAIGDataset *>(poDS);

    if( nBlockYOff < 0 || nBlockYOff > poODS->nRasterYSize - 1 ||
        nBlockXOff != 0 || panLineOffset == nullptr || poODS->fp == nullptr )
        return CE_Failure;

    if( panLineOffset[nBlockYOff] == 0 )
    {
        for( int iPrevLine = 1; iPrevLine <= nBlockYOff; iPrevLine++ )
            if( panLineOffset[iPrevLine] == 0 )
                IReadBlock(nBlockXOff, iPrevLine - 1, nullptr);
    }

    if( panLineOffset[nBlockYOff] == 0 )
        return CE_Failure;

    if( poODS->Seek(panLineOffset[nBlockYOff]) != 0 )
    {
        CPLError(CE_Failure, CPLE_FileIO,
                 "Can't seek to offset %lu in input file to read data.",
                 static_cast<long unsigned int>(panLineOffset[nBlockYOff]));
        return CE_Failure;
    }

    for( int iPixel = 0; iPixel < poODS->nRasterXSize; )
    {
        // Suck up any pre-white space.
        char chNext = '\0';
        do {
            chNext = poODS->Getc();
        } while( isspace(static_cast<unsigned char>(chNext)) );

        char szToken[500] = { '\0' };
        int iTokenChar = 0;
        while( chNext != '\0' && !isspace((unsigned char)chNext) )
        {
            if( iTokenChar == sizeof(szToken) - 2 )
            {
                CPLError(CE_Failure, CPLE_FileIO,
                         "Token too long at scanline %d.", nBlockYOff);
                return CE_Failure;
            }

            szToken[iTokenChar++] = chNext;
            chNext = poODS->Getc();
        }

        if( chNext == '\0' &&
            (iPixel != poODS->nRasterXSize - 1 ||
            nBlockYOff != poODS->nRasterYSize - 1) )
        {
            CPLError(CE_Failure, CPLE_FileIO, "File short, can't read line %d.",
                     nBlockYOff);
            return CE_Failure;
        }

        szToken[iTokenChar] = '\0';

        if( pImage != nullptr )
        {
            if( eDataType == GDT_Float64 )
                reinterpret_cast<double *>(pImage)[iPixel] = CPLAtofM(szToken);
            else if( eDataType == GDT_Float32 )
                reinterpret_cast<float *>(pImage)[iPixel] =
                    DoubleToFloatClamp(CPLAtofM(szToken));
            else
                reinterpret_cast<GInt32 *>(pImage)[iPixel] =
                    static_cast<GInt32>(atoi(szToken));
        }

        iPixel++;
    }

    if( nBlockYOff < poODS->nRasterYSize - 1 )
        panLineOffset[nBlockYOff + 1] = poODS->Tell();

    return CE_None;
}
예제 #2
0
파일: g2_unpack7.c 프로젝트: norulz/zyGrib
g2int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum,g2int *igdstmpl,
               g2int idrsnum,g2int *idrstmpl,g2int ndpts,g2float **fld)
//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .      .    .                                       .
// SUBPROGRAM:    g2_unpack7 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
//
// ABSTRACT: This subroutine unpacks Section 7 (Data Section)
//           as defined in GRIB Edition 2.
//
// PROGRAM HISTORY LOG:
// 2002-10-31  Gilbert
// 2002-12-20  Gilbert - Added GDT info to arguments
//                       and added 5.51 processing.
// 2003-08-29  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
// 2004-12-16  Taylor   - Added check on comunpack return code.
// 2008-12-23  Wesley   - Initialize Number of data points unpacked
//
// USAGE:    int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum,
//                          g2int *igdstmpl, g2int idrsnum,
//                          g2int *idrstmpl, g2int ndpts,g2float **fld)
//   INPUT ARGUMENTS:
//     cgrib    - char array containing Section 7 of the GRIB2 message
//     iofst    - Bit offset of the beginning of Section 7 in cgrib.
//     igdsnum  - Grid Definition Template Number ( see Code Table 3.0)
//                ( Only used for DRS Template 5.51 )
//     igdstmpl - Pointer to an integer array containing the data values for
//                the specified Grid Definition
//                Template ( N=igdsnum ).  Each element of this integer
//                array contains an entry (in the order specified) of Grid
//                Definition Template 3.N
//                ( Only used for DRS Template 5.51 )
//     idrsnum  - Data Representation Template Number ( see Code Table 5.0)
//     idrstmpl - Pointer to an integer array containing 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
//     ndpts    - Number of data points unpacked and returned.
//
//   OUTPUT ARGUMENTS:      
//     iofst    - Bit offset at the end of Section 7, returned.
//     fld      - Pointer to a float array containing the unpacked data field.
//
//   RETURN VALUES:
//     ierr     - Error return code.
//                0 = no error
//                2 = Not section 7
//                4 = Unrecognized Data Representation Template
//                5 = need one of GDT 3.50 through 3.53 to decode DRT 5.51
//                6 = memory allocation error
//                7 = corrupt section 7.
//
// REMARKS: None
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$//
{
      g2int ierr,isecnum;
      g2int ipos,lensec;
      g2float *lfld;

      ierr=0;
      *fld=0;     //NULL

      gbit(cgrib,&lensec,*iofst,32);        // Get Length of Section
      *iofst=*iofst+32;    
      gbit(cgrib,&isecnum,*iofst,8);         // Get Section Number
      *iofst=*iofst+8;

      if ( isecnum != 7 ) {
         ierr=2;
         //fprintf(stderr,"g2_unpack7: Not Section 7 data.\n");
         return(ierr);
      }

      ipos=(*iofst/8);
      lfld=(g2float *)calloc(ndpts ? ndpts : 1,sizeof(g2float));
      if (lfld == 0) {
         ierr=6;
         return(ierr);
      }
      *fld=lfld;

      if (idrsnum == 0) 
        simunpack(cgrib+ipos,idrstmpl,ndpts,lfld);
      else if (idrsnum == 2 || idrsnum == 3) {
        if (comunpack(cgrib+ipos,lensec,idrsnum,idrstmpl,ndpts,lfld) != 0) {
          return 7;
        }
      }
      else if( idrsnum == 4 ) {
        // Grid point data - IEEE Floating Point Data
        static const int one = 1;
        int is_lsb = *((char*)&one) == 1;
        if (idrstmpl[0] == 1) {
          // IEEE754 single precision
          memcpy(lfld, cgrib+ipos, 4 * ndpts );
          if( is_lsb ) {
              int i;
              unsigned char* ch_fld = (unsigned char*) lfld;
              for(i=0;i<ndpts;i++)
              {
                  unsigned char temp = ch_fld[i*4];
                  ch_fld[i*4] = ch_fld[i*4+3];
                  ch_fld[i*4+3] = temp;
                  temp = ch_fld[i*4+1];
                  ch_fld[i*4+1] = ch_fld[i*4+2];
                  ch_fld[i*4+2] = temp;
              }
          }
        }
        else if( idrstmpl[0] == 2) {
          // IEEE754 double precision
          // FIXME? due to the interface: we downgrade it to float
          int i;
          unsigned char* src = cgrib+ipos;
          if( is_lsb ) {
              for(i=0;i<ndpts;i++) {
                  unsigned char temp[8];
                  double d;
                  {
                    int j;
                    for(j = 0; j < 8; j++ )
                      temp[j] = src[i * 8 + 7 - j];
                  }
                  memcpy(&d, temp, 8);
                  lfld[i] = DoubleToFloatClamp(d);
              }
          }
          else {
              for(i=0;i<ndpts;i++) {
                  double d;
                  memcpy(&d, src + i * 8, 8);
                  lfld[i] = DoubleToFloatClamp(d);
              }
          }
        }
        else {
            fprintf(stderr,"g2_unpack7: Invalid precision=%ld for Data Section 5.4.\n", idrstmpl[0]);
            ierr=5;
            free(lfld);
            *fld=0;     //NULL
            return(ierr);
        }
      }
      else if (idrsnum == 50) {            // Spectral Simple
        simunpack(cgrib+ipos,idrstmpl,ndpts-1,lfld+1);
        rdieee(idrstmpl+4,lfld+0,1);
      }
      else if (idrsnum == 51)              //  Spectral complex
        if ( igdsnum>=50 && igdsnum <=53 ) 
          specunpack(cgrib+ipos,idrstmpl,ndpts,igdstmpl[0],igdstmpl[2],igdstmpl[2],lfld);
        else {
          fprintf(stderr,"g2_unpack7: Cannot use GDT 3.%d to unpack Data Section 5.51.\n",(int)igdsnum);
          ierr=5;
          free(lfld);
          *fld=0;     //NULL
          return(ierr);
        }
#ifdef USE_JPEG2000
      else if (idrsnum == 40 || idrsnum == 40000) {
        jpcunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld);
        }
#endif  /* USE_JPEG2000 */
#ifdef USE_PNG
      else if (idrsnum == 41 || idrsnum == 40010) {
        pngunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld);
        }
#endif  /* USE_PNG */
      else {
        fprintf(stderr,"g2_unpack7: Data Representation Template 5.%d not yet implemented.\n",(int)idrsnum);
        ierr=4;
        free(lfld);
        *fld=0;     //NULL
        return(ierr);
      }

      *iofst=*iofst+(8*lensec);
      
      return(ierr);    // End of Section 7 processing

}