Exemple #1
0
//----------------------------------------------
// SECTION 3: BIT MAP SECTION (BMS)
//----------------------------------------------
bool GribV1Record::readGribSection3_BMS(ZUFILE* file) {
    fileOffset3 = zu_tell(file);
    if (! hasBMS) {
        sectionSize3 = 0;
        return ok;
    }
    sectionSize3 = readInt3(file);
    (void) readChar(file);
    int bitMapFollows = readInt2(file);

    if (bitMapFollows != 0) {
        return ok;
    }
    BMSbits = new zuchar[sectionSize3-6];
    if (!BMSbits) {
        //erreur("Record: out of memory");
        ok = false;
    }
    for (zuint i=0; i<sectionSize3-6; i++) {
        BMSbits[i] = readChar(file);
    }
    return ok;
}
Exemple #2
0
static bool patchApplyIPS(const char *patchname, u8 **r, int *s)
{
  // from the IPS spec at http://zerosoft.zophar.net/ips.htm
  FILE *f = fopen(patchname, "rb");
  if(!f)
    return false;

  bool result = false;

  u8 *rom = *r;
  int size = *s;
  if(fgetc(f) == 'P' &&
     fgetc(f) == 'A' &&
     fgetc(f) == 'T' &&
     fgetc(f) == 'C' &&
     fgetc(f) == 'H') {
    int b;
    int offset;
    int len;

    result = true;

    for(;;) {
      // read offset
      offset = readInt3(f);
      // if offset == EOF, end of patch
      if(offset == 0x454f46 || offset == -1)
        break;
      // read length
      len = readInt2(f);
      if(!len) {
        // len == 0, RLE block
        len = readInt2(f);
        // byte to fill
        int c = fgetc(f);
        if(c == -1)
          break;
        b = (u8)c;
      } else
        b= -1;
      // check if we need to reallocate our ROM
      if((offset + len) >= size) {
        size *= 2;
        rom = (u8 *)realloc(rom, size);
        *r = rom;
        *s = size;
      }
      if(b == -1) {
        // normal block, just read the data
        if(fread(&rom[offset], 1, len, f) != (size_t)len)
          break;
      } else {
        // fill the region with the given byte
        while(len--) {
          rom[offset++] = b;
        }
      }
    }
  }
  // close the file
  fclose(f);

  return result;
}
Exemple #3
0
//----------------------------------------------
// SECTION 4: BINARY DATA SECTION (BDS)
//----------------------------------------------
bool GribV1Record::readGribSection4_BDS(ZUFILE* file) {
    fileOffset4  = zu_tell(file);
    sectionSize4 = readInt3(file);  // byte 1-2-3

    zuchar flags  = readChar(file);			// byte 4
    scaleFactorE = readSignedInt2(file);	// byte 5-6
    refValue     = readFloat4(file);		// byte 7-8-9-10
    nbBitsInPack = readChar(file);			// byte 11
    scaleFactorEpow2 = pow(2.0,scaleFactorE);
    unusedBitsEndBDS = flags & 0x0F;
    isGridData      = (flags&0x80) ==0;
    isSimplePacking = (flags&0x80) ==0;
    isFloatValues   = (flags&0x80) ==0;

//printf("BDS type=%3d - bits=%02d - level %3d - %d\n", dataType, nbBitsInPack, levelType,levelValue);

    if (! isGridData) {
        //erreur("Record: need grid data");
        ok = false;
    }
    if (! isSimplePacking) {
        //erreur("Record: need simple packing");
        ok = false;
    }
    if (! isFloatValues) {
        //erreur("Record: need double values");
        ok = false;
    }

    if (!ok) {
        return ok;
    }

    // Allocate memory for the data
    data = new float[Ni*Nj];
    if (!data) {
        //erreur("Record: out of memory");
        ok = false;
    }

    zuint  startbit  = 0;
    int  datasize = sectionSize4-11;
    zuchar *buf = new zuchar[datasize+4];  // +4 pour simplifier les decalages ds readPackedBits
    if (!buf) {
        //erreur("Record: out of memory");
        ok = false;
    }
    if (zu_read(file, buf, datasize) != datasize) {
        //erreur("Record: data read error");
        ok = false;
        eof = true;
    }
    if (!ok) {
        return ok;
    }
    // Initialize the las 4 bytes of buf since we didn't read them
    buf[datasize+0] = buf[datasize+1] = buf[datasize+2] = buf[datasize+3] = 0;

    // Read data in the order given by isAdjacentI
    zuint i, j, x;
    int ind;
    if (isAdjacentI) {
        for (j=0; j<Nj; j++) {
            for (i=0; i<Ni; i++) {
                if (!hasDiDj && !isScanJpositive) {
                    ind = (Nj-1 -j)*Ni+i;
                }
                else {
                    ind = j*Ni+i;
                }
                if (hasValue(i,j)) {
                    x = readPackedBits(buf, startbit, nbBitsInPack);
                    data[ind] = (refValue + x*scaleFactorEpow2)/decimalFactorD;
                    startbit += nbBitsInPack;
                }
                else {
                    data[ind] = (float) GRIB_NOTDEF;
                }
            }
        }
    }
    else {
        for (i=0; i<Ni; i++) {
            for (j=0; j<Nj; j++) {
                if (!hasDiDj && !isScanJpositive) {
                    ind = (Nj-1 -j)*Ni+i;
                }
                else {
                    ind = j*Ni+i;
                }
                if (hasValue(i,j)) {
                    x = readPackedBits(buf, startbit, nbBitsInPack);
                    startbit += nbBitsInPack;
                    data[ind] = (refValue + x*scaleFactorEpow2)/decimalFactorD;
                }
                else {
                    data[ind] = (float)GRIB_NOTDEF;
                }
            }
        }
    }

    if (buf) {
        delete [] buf;
        buf = NULL;
    }
    return ok;
}
Exemple #4
0
//----------------------------------------------
// SECTION 2: THE GRID DESCRIPTION SECTION (GDS)
//----------------------------------------------
bool GribV1Record::readGribSection2_GDS(ZUFILE* file) {
    if (! hasGDS)
        return 0;
    fileOffset2 = zu_tell(file);
    sectionSize2 = readInt3(file);  // byte 1-2-3
    readChar(file);			// byte 4 => NV
    readChar(file); 			// byte 5 => PV
    gridType = readChar(file); 		// byte 6

    if (gridType != 0) {
        erreur("Record: unknown grid type GDS(6) : %d",gridType);
        ok = false;
    }

    Ni  = readInt2(file);				// byte 7-8
    Nj  = readInt2(file);				// byte 9-10
    La1 = readSignedInt3(file)/1000.0;	// byte 11-12-13
    Lo1 = readSignedInt3(file)/1000.0;	// byte 14-15-16
    resolFlags = readChar(file);		// byte 17
    La2 = readSignedInt3(file)/1000.0;	// byte 18-19-20
    Lo2 = readSignedInt3(file)/1000.0;	// byte 21-22-23

    if (Lo1>=0 && Lo1<=180 && Lo2<0) {
        Lo2 += 360.0;    // cross the 180 deg meridien,beetwen alaska and russia
    }

    Di  = readSignedInt2(file)/1000.0;	// byte 24-25
    Dj  = readSignedInt2(file)/1000.0;	// byte 26-27

    while ( Lo1> Lo2   &&  Di >0) {   // horizontal size > 360 °
        Lo1 -= 360.0;
    }

    double val=Lo2+Di;
    while(val>=360) val-=360;
    if(val==Lo1)
        isFull=true;

    hasDiDj =(resolFlags&0x80) !=0;

    scanFlags = readChar(file);			// byte 28
    isScanIpositive = (scanFlags&0x80) ==0;
    isScanJpositive = (scanFlags&0x40) !=0;
    isAdjacentI     = (scanFlags&0x20) ==0;

        if (Lo2 > Lo1) {
            lonMin = Lo1;
            lonMax = Lo2;
        }
        else {
            lonMin = Lo2;
            lonMax = Lo1;
        }
        if (La2 > La1) {
            latMin = La1;
            latMax = La2;
        }
        else {
            latMin = La2;
            latMax = La1;
        }
        if (Ni<=1 || Nj<=1) {
                erreur("Recordd: Ni=%u Nj=%u",Ni,Nj);
                ok = false;
        }
        else {
                Di = (Lo2-Lo1) / (Ni-1);
                Dj = (La2-La1) / (Nj-1);
        }

if (false) {
printf("====\n");
printf("Lo1=%f Lo2=%f    La1=%f La2=%f\n", Lo1,Lo2,La1,La2);
printf("Ni=%u Nj=%u\n", Ni,Nj);
printf("hasDiDj=%d Di,Dj=(%f %f)\n", hasDiDj, Di,Dj);
printf("hasBMS=%d\n", hasBMS);
printf("isScanIpositive=%d isScanJpositive=%d isAdjacentI=%d\n",
                        isScanIpositive,isScanJpositive,isAdjacentI );
}
    return ok;
}
Exemple #5
0
//==============================================================
// Lecture des donnees
//==============================================================
//----------------------------------------------
// SECTION 0: THE INDICATOR SECTION (IS)
//----------------------------------------------
bool GribV1Record::readGribSection0_IS(ZUFILE* file) {
    char    strgrib[4];
    memset (strgrib, 0, sizeof (strgrib));
    zuint initFoffset;
    fileOffset0 = zu_tell(file);
    initFoffset=fileOffset0;
#if 1
    char buf[1];
    memset (buf, 0, sizeof (buf));
    while(true)
    {
        if(zu_read(file,buf,1)!=1) break;
        ++fileOffset0;
        if(buf[0]!='G')
            continue;
        if(zu_read(file,buf,1)!=1) break;
        ++fileOffset0;
        if(buf[0]!='R')
        {
            if(buf[0]=='G')
                zu_seek(file,--fileOffset0,SEEK_SET);
            continue;
        }
        if(zu_read(file,buf,1)!=1) break;
        ++fileOffset0;
        if(buf[0]!='I')
        {
            if(buf[0]=='G')
                zu_seek(file,--fileOffset0,SEEK_SET);
            continue;
        }
        if(zu_read(file,buf,1)!=1) break;
        ++fileOffset0;
        if(buf[0]!='B')
        {
            if(buf[0]=='G')
                zu_seek(file,--fileOffset0,SEEK_SET);
            continue;
        }
        strgrib[0]='G';
        strgrib[1]='R';
        strgrib[2]='I';
        strgrib[3]='B';
        break;
    }
#else
    while((zu_read(file, strgrib, 4) == 4) &&
          (strgrib[0] != 'G' || strgrib[1] != 'R' ||
           strgrib[2] != 'I' || strgrib[3] != 'B')) {
          zu_seek(file,++fileOffset0,SEEK_SET);
    }
#endif
    if(strgrib[0] != 'G' || strgrib[1] != 'R' ||
            strgrib[2] != 'I' || strgrib[3] != 'B') {
        if((fileOffset0-10)>initFoffset) // displaying error msg only if we are really far from initial offset
            qWarning() << "Can't find next record / EOF - offset=" << fileOffset0 << ", initOffset=" << initFoffset ;
        ok = false;
        eof = true;
        return false;
    }


    seekStart=zu_tell(file)-4;
    totalSize = readInt3(file);


    //qWarning() << "Start = " << seekStart << ", size = " << totalSize;

    editionNumber = readChar(file);
    if (editionNumber != 1)  {
        ok = false;
        eof = true;
        return false;
    }

    return true;
}