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; }
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 }