Beispiel #1
0
FFHeaderI & FFHeaderI::operator = (FFHeaderI const & ffh)
{
	if (&ffh != this)
	{
		if (data) free(data);
		if (filename) delete[] filename;
		
		filename = 0;
		data = 0;
		length = ffh.length;
		
		if (ffh.filename)
		{
			filename = new char [1+strlen(ffh.filename)];
			strcpy(filename,ffh.filename);
		}
		if (ffh.data)
		{
			data = malloc(length);
			memcpy(data,ffh.data,length);
		}
		ptrdiff_t offset = (size_t)data - (size_t)ffh.data;
		for (int i=0; i<FFHI_HASHTABLESIZE; ++i)
		{
			for (CLIF<FFDataI> i_file(&ffh.files[i]); !i_file.done(); i_file.next())
			{
				files[i].add_entry(FFDataI(i_file(),offset));
			}
		}
	}
	return *this;
}
Beispiel #2
0
FFHeaderI::FFHeaderI(FFHeaderI const & ffh)
: filename(0)
, data(0)
, length(ffh.length)
,should_be_kept(ffh.should_be_kept)
{
	if (ffh.filename)
	{
		filename = new char [1+strlen(ffh.filename)];
		strcpy(filename,ffh.filename);
	}
	if (ffh.data)
	{
		data = malloc(length);
		memcpy(data,ffh.data,length);
	}
	ptrdiff_t offset = (size_t)data - (size_t)ffh.data;
	for (int i=0; i<FFHI_HASHTABLESIZE; ++i)
	{
		for (CLIF<FFDataI> i_file(&ffh.files[i]); !i_file.done(); i_file.next())
		{
			files[i].add_entry(FFDataI(i_file(),offset));
		}
	}
}
Beispiel #3
0
void const * FFHeaderI::FindFile(char const * name, size_t * lengthP) const
{
	for (CLIF<FFDataI> i_file(&files[HashFunction(name)]); !i_file.done(); i_file.next())
	{
		if (i_file()==name)
		{
			if (lengthP) *lengthP = i_file().GetLength();
			return i_file().GetDataPointer();
		}
	}
	return 0;
}
Beispiel #4
0
CPLErr MSGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
        
    MSGDataset  *poGDS = (MSGDataset *) poDS;


    int iBytesPerPixel = 1;
    if (eDataType == GDT_UInt16)
      iBytesPerPixel = 2;
    else if (eDataType == GDT_Float32)
      iBytesPerPixel = 4;
/* -------------------------------------------------------------------- */
/*      Calculate the correct input file name based on nBlockYOff       */
/* -------------------------------------------------------------------- */

    int strip_number;
    int iChannel = poGDS->command.iChannel(1 + ((nBand - 1) % poGDS->command.iNrChannels()));

    if (fScanNorth)
      strip_number = nBlockYOff + 1;
    else
      strip_number = poGDS->command.iNrStrips(iChannel) - nBlockYOff;

    std::string strip_input_file = poGDS->command.sFileName(iSatellite, nBand, strip_number);
    
/* -------------------------------------------------------------------- */
/*      Open the input file                                             */
/* -------------------------------------------------------------------- */
    if (access(strip_input_file.c_str(), 0) == 0) // does it exist?
    {
      std::ifstream i_file (strip_input_file.c_str(), std::ios::in|std::ios::binary);

      if (i_file.good())
      {
        XRITHeaderParser xhp (i_file);

        if (xhp.isValid())
        {
          std::vector <short> QualityInfo;
          unsigned short chunck_height = xhp.nrRows();
          unsigned short chunck_bpp = xhp.nrBitsPerPixel();
          unsigned short chunck_width = xhp.nrColumns();
          unsigned __int8 NR = (unsigned __int8)chunck_bpp;
          unsigned int nb_ibytes = xhp.dataSize();
          int iShift = 0;
          bool fSplitStrip = false; // in the split strip the "shift" only happens before the split "row"
          int iSplitRow = 0;
          if (iChannel == 12)
          {
            iSplitRow = iSplitLine % xhp.nrRows();
            int iSplitBlock = iSplitLine / xhp.nrRows();
            fSplitStrip = (nBlockYOff == iSplitBlock); // in the split strip the "shift" only happens before the split "row"

            // When iLowerShift > 0, the lower HRV image is shifted to the right
            // When iLowerShift < 0, the lower HRV image is shifted to the left
            // The available raster may be wider than needed, so that time series don't fall outside the raster.
            
            if (nBlockYOff <= iSplitBlock)
              iShift = -iLowerShift;
            // iShift < 0 means upper image moves to the left
            // iShift > 0 means upper image moves to the right
          }
          
          std::auto_ptr< unsigned char > ibuf( new unsigned char[nb_ibytes]);
          
          if (ibuf.get() == 0)
          {
             CPLError( CE_Failure, CPLE_AppDefined, 
                  "Not enough memory to perform wavelet decompression\n");
            return CE_Failure;
          }

          i_file.read( (char *)(ibuf.get()), nb_ibytes);
          
          Util::CDataFieldCompressedImage  img_compressed(ibuf.release(),
                                  nb_ibytes*8,
                                  (unsigned char)chunck_bpp,
                                  chunck_width,
                                  chunck_height      );
          
          Util::CDataFieldUncompressedImage img_uncompressed;

          //****************************************************
          //*** Here comes the wavelets decompression routine
          COMP::DecompressWT(img_compressed, NR, img_uncompressed, QualityInfo);
          //****************************************************

          // convert:
          // Depth:
          // 8 bits -> 8 bits
          // 10 bits -> 16 bits (img_uncompressed contains the 10 bits data in packed form)
          // Geometry:
          // chunck_width x chunck_height to nBlockXSize x nBlockYSize

          // cases:
          // combination of the following:
          // - scan direction can be north or south
          // - eDataType can be GDT_Byte, GDT_UInt16 or GDT_Float32
          // - nBlockXSize == chunck_width or nBlockXSize > chunck_width
          // - when nBlockXSize > chunck_width, fSplitStrip can be true or false
          // we won't distinguish the following cases:
          // - NR can be == 8 or != 8
          // - when nBlockXSize > chunck_width, iShift iMinCOff-iMaxCOff <= iShift <= 0

          int nBlockSize = nBlockXSize * nBlockYSize;
          int y = chunck_width * chunck_height;
          int iStep = -1;
          if (fScanNorth) // image is the other way around
          {
            y = -1; // See how y is used below: += happens first, the result is used in the []
            iStep = 1;
          }

          COMP::CImage cimg (img_uncompressed); // unpack
          if (eDataType == GDT_Byte)
          {
            if (nBlockXSize == chunck_width) // optimized version
            {
              if (poGDS->command.cDataConversion == 'B')
              {
                for( int i = 0; i < nBlockSize; ++i )
                    ((GByte *)pImage)[i] = cimg.Get()[y+=iStep] / 4;
              }
              else
              {
                for( int i = 0; i < nBlockSize; ++i )
                    ((GByte *)pImage)[i] = cimg.Get()[y+=iStep];
              }
            }
            else
            {
              // initialize to 0's (so that it does not have to be done in an 'else' statement <performance>)
              memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);
              if (poGDS->command.cDataConversion == 'B')
              {
                for( int j = 0; j < chunck_height; ++j ) // assumption: nBlockYSize == chunck_height
                { 
                  int iXOffset = j * nBlockXSize + iShift;
                  iXOffset += nBlockXSize - iLowerWestColumnPlanned - 1; // Position the HRV part in the frame; -1 to compensate the pre-increment in the for-loop
                  if (fSplitStrip && (j >= iSplitRow)) // In splitstrip, below splitline, thus do not shift!!
                    iXOffset -= iShift;
                  for (int i = 0; i < chunck_width; ++i)
                    ((GByte *)pImage)[++iXOffset] = cimg.Get()[y+=iStep] / 4;
                }
              }
              else
              {
                for( int j = 0; j < chunck_height; ++j ) // assumption: nBlockYSize == chunck_height
                { 
                  int iXOffset = j * nBlockXSize + iShift;
                  iXOffset += nBlockXSize - iLowerWestColumnPlanned - 1; // Position the HRV part in the frame; -1 to compensate the pre-increment in the for-loop
                  if (fSplitStrip && (j >= iSplitRow)) // In splitstrip, below splitline, thus do not shift!!
                    iXOffset -= iShift;
                  for (int i = 0; i < chunck_width; ++i)
                    ((GByte *)pImage)[++iXOffset] = cimg.Get()[y+=iStep];
                }
              }
            }
          }
          else if (eDataType == GDT_UInt16) // this is our "normal case" if scan direction is South: 10 bit MSG data became 2 bytes per pixel
          {
            if (nBlockXSize == chunck_width) // optimized version
            {
              for( int i = 0; i < nBlockSize; ++i )
                  ((GUInt16 *)pImage)[i] = cimg.Get()[y+=iStep];
            }
            else
            {
              // initialize to 0's (so that it does not have to be done in an 'else' statement <performance>)
              memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);
              for( int j = 0; j < chunck_height; ++j ) // assumption: nBlockYSize == chunck_height
              {
                int iXOffset = j * nBlockXSize + iShift;
                iXOffset += nBlockXSize - iLowerWestColumnPlanned - 1; // Position the HRV part in the frame; -1 to compensate the pre-increment in the for-loop
                if (fSplitStrip && (j >= iSplitRow)) // In splitstrip, below splitline, thus do not shift!!
                  iXOffset -= iShift;
                for (int i = 0; i < chunck_width; ++i)
                  ((GUInt16 *)pImage)[++iXOffset] = cimg.Get()[y+=iStep];
              }
            }
          }
          else if (eDataType == GDT_Float32) // radiometric calibration is requested
          {
            if (nBlockXSize == chunck_width) // optimized version
            {
              for( int i = 0; i < nBlockSize; ++i )
                ((float *)pImage)[i] = (float)rRadiometricCorrection(cimg.Get()[y+=iStep], iChannel, nBlockYOff * nBlockYSize + i / nBlockXSize, i % nBlockXSize, poGDS);
            }
            else
            {
              // initialize to 0's (so that it does not have to be done in an 'else' statement <performance>)
              memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);
              for( int j = 0; j < chunck_height; ++j ) // assumption: nBlockYSize == chunck_height
              {
                int iXOffset = j * nBlockXSize + iShift;
                iXOffset += nBlockXSize - iLowerWestColumnPlanned - 1; // Position the HRV part in the frame; -1 to compensate the pre-increment in the for-loop
                if (fSplitStrip && (j >= iSplitRow)) // In splitstrip, below splitline, thus do not shift!!
                  iXOffset -= iShift;
                int iXFrom = nBlockXSize - iLowerWestColumnPlanned + iShift; // i is used as the iCol parameter in rRadiometricCorrection
                int iXTo = nBlockXSize - iLowerWestColumnPlanned + chunck_width + iShift;
                for (int i = iXFrom; i < iXTo; ++i) // range always equal to chunck_width .. this is to utilize i to get iCol
                  ((float *)pImage)[++iXOffset] = (float)rRadiometricCorrection(cimg.Get()[y+=iStep], iChannel, nBlockYOff * nBlockYSize + j, (fSplitStrip && (j >= iSplitRow))?(i - iShift):i, poGDS);
              }
            }
          }
        }
        else // header could not be opened .. make sure block contains 0's
          memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);
      }
      else // file could not be opened .. make sure block contains 0's
        memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);

      i_file.close();
    }
    else // file does not exist .. make sure block contains 0's
      memset(pImage, 0, nBlockXSize * nBlockYSize * iBytesPerPixel);

    return CE_None;
}
Beispiel #5
0
MSGRasterBand::MSGRasterBand( MSGDataset *poDS, int nBand )
: fScanNorth(false)
, iLowerShift(0)
, iSplitLine(0)
, iLowerWestColumnPlanned(0)

{
    this->poDS = poDS;
    this->nBand = nBand;
		
    // Find if we're dealing with MSG1, MSG2, MSG3 or MSG4
    // Doing this per band is the only way to guarantee time-series when the satellite is changed

    std::string sPrologueFileName = poDS->command.sPrologueFileName(poDS->iCurrentSatellite, nBand);
    bool fPrologueExists = (access(sPrologueFileName.c_str(), 0) == 0);

    // Make sure we're testing for MSG1,2,3 or 4 exactly once, start with the most recently used, and remember it in the static member for the next round.
    if (!fPrologueExists)
    {
      poDS->iCurrentSatellite = 1 + poDS->iCurrentSatellite % MAX_SATELLITES;
      sPrologueFileName = poDS->command.sPrologueFileName(poDS->iCurrentSatellite, nBand);
      fPrologueExists = (access(sPrologueFileName.c_str(), 0) == 0);
      int iTries = 2;
      while (!fPrologueExists && (iTries < MAX_SATELLITES))
      {
        poDS->iCurrentSatellite = 1 + poDS->iCurrentSatellite % MAX_SATELLITES;
        sPrologueFileName = poDS->command.sPrologueFileName(poDS->iCurrentSatellite, nBand);
        fPrologueExists = (access(sPrologueFileName.c_str(), 0) == 0);
        ++iTries;
      }
      if (!fPrologueExists) // assume missing prologue file, keep original satellite number
      {
        poDS->iCurrentSatellite = 1 + poDS->iCurrentSatellite % MAX_SATELLITES;
        sPrologueFileName = poDS->command.sPrologueFileName(poDS->iCurrentSatellite, nBand);
      }
    }

    iSatellite = poDS->iCurrentSatellite; // From here on, the satellite that corresponds to this band is settled to the current satellite

    nBlockXSize = poDS->GetRasterXSize();
    nBlockYSize = poDS->GetRasterYSize();

/* -------------------------------------------------------------------- */
/*      Open an input file and capture the header for the nr. of bits.  */
/* -------------------------------------------------------------------- */
    int iStrip = 1;
    int iChannel = poDS->command.iChannel(1 + ((nBand - 1) % poDS->command.iNrChannels()));
    std::string input_file = poDS->command.sFileName(iSatellite, nBand, iStrip);
    while ((access(input_file.c_str(), 0) != 0) && (iStrip <= poDS->command.iNrStrips(iChannel))) // compensate for missing strips
      input_file = poDS->command.sFileName(iSatellite, nBand, ++iStrip);

    if (iStrip <= poDS->command.iNrStrips(iChannel))
    {
      std::ifstream i_file (input_file.c_str(), std::ios::in|std::ios::binary);

      if (i_file.good())
      {
        XRITHeaderParser xhp (i_file);

        if (xhp.isValid())
        {
          // Data type is either 8 or 16 bits .. we tell this to GDAL here
          eDataType = GDT_Byte; // default .. always works
          if (xhp.nrBitsPerPixel() > 8)
          {
            if (poDS->command.cDataConversion == 'N')
              eDataType = GDT_UInt16; // normal case: MSG 10 bits data
            else if (poDS->command.cDataConversion == 'B')
              eDataType = GDT_Byte; // output data type Byte
            else
              eDataType = GDT_Float32; // Radiometric calibration
          }

          // make IReadBlock be called once per file
          nBlockYSize = xhp.nrRows();

          // remember the scan direction

          fScanNorth = xhp.isScannedNorth();
        }
      }

      i_file.close();
    }
    else if (nBand > 1)
    {
      // missing entire band .. take data from first band
      MSGRasterBand* pFirstRasterBand = (MSGRasterBand*)poDS->GetRasterBand(1);
      eDataType = pFirstRasterBand->eDataType;
      nBlockYSize = pFirstRasterBand->nBlockYSize;
      fScanNorth = pFirstRasterBand->fScanNorth;
    }
    else // also first band is missing .. do something for fail-safety
    {
      eDataType = GDT_Byte; // default .. always works
      if (poDS->command.cDataConversion == 'N')
        eDataType = GDT_UInt16; // normal case: MSG 10 bits data
      else if (poDS->command.cDataConversion == 'B')
        eDataType = GDT_Byte; // output data type Byte
      else
        eDataType = GDT_Float32; // Radiometric calibration

      // nBlockYSize : default
      // fScanNorth : default

    }
/* -------------------------------------------------------------------- */
/*      For the HRV band, read the prologue for shift and splitline.    */
/* -------------------------------------------------------------------- */

    if (iChannel == 12)
    {
      if (fPrologueExists)
      {
        std::ifstream p_file(sPrologueFileName.c_str(), std::ios::in|std::ios::binary);
        XRITHeaderParser xhp(p_file);
        Prologue pp;
        if (xhp.isValid() && xhp.isPrologue())
          pp.read(p_file);
        p_file.close();

        iLowerShift = pp.idr()->PlannedCoverageHRV->UpperWestColumnPlanned - pp.idr()->PlannedCoverageHRV->LowerWestColumnPlanned;
        iSplitLine = abs(pp.idr()->PlannedCoverageHRV->UpperNorthLinePlanned - pp.idr()->PlannedCoverageHRV->LowerNorthLinePlanned) + 1; // without the "+ 1" the image of 1-Jan-2005 splits incorrectly
        iLowerWestColumnPlanned = pp.idr()->PlannedCoverageHRV->LowerWestColumnPlanned;
      }
    }

/* -------------------------------------------------------------------- */
/*  Initialize the ReflectanceCalculator with the band-dependent info.  */
/* -------------------------------------------------------------------- */

    int iCycle = 1 + (nBand - 1) / poDS->command.iNrChannels();
    std::string sTimeStamp = poDS->command.sCycle(iCycle);

    m_rc = new ReflectanceCalculator(sTimeStamp, rRTOA[iChannel-1]);
}