Exemplo n.º 1
0
bool ossimKakaduJ2kReader::open()
{
   static const char MODULE[] = "ossimKakaduJ2kReader::open";

   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << MODULE << " entered...\n";
   }
   
   bool result = false;
   
   if(isOpen())
   {
      closeEntry();
   }

   // Open up a stream to the file.
   theFileStr.open(theImageFile.c_str(), ios::in | ios::binary);
   if ( theFileStr.good() )
   {
      //---
      // Check for the Start Of Codestream (SOC) and Size (SIZ) markers which
      // are required as first and second fields in the main header.
      //---
      ossim_uint16 soc;
      ossim_uint16 siz;
      theFileStr.read((char*)&soc,  2);
      theFileStr.read((char*)&siz,  2);
      
      if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN) // Alway big endian.
      {
         ossimEndian().swap(soc);
         ossimEndian().swap(siz);
      }

      if ( (soc == SOC_MARKER) && (siz == SIZ_MARKER) )
      {
         // Read in and store the size record.
         theSizRecord.parseStream(theFileStr);

         // Position to start of code stream prior to create call.
         theFileStr.seekg(0);
 
         //---
         // Initialize the codestream.  The class ossimKakaduNitfReader is a
         // kdu_compressed source so we feed ourself to the codestream.
         //
         // TODO:  Currently no kdu_thread_env.  This should be implemented for
         // speed...
         //---
         
         //---
         // Construct multi-threaded processing environment if required.
         // Temp hard coded to a single thread.
         //---
         
         if (theThreadEnv)
         {
            theThreadEnv->terminate(NULL, true);
            theThreadEnv->destroy();
         }
         else
         {
            theThreadEnv = new kdu_thread_env();
         }
         
         theThreadEnv->create(); // Creates the single "owner" thread

         // Check for threads in prefs file.
         ossim_uint32 threads = 1;
         const char* lookup = ossimPreferences::instance()->findPreference("kakadu_threads");
         if ( lookup )
         {
            threads = ossimString::toUInt32(lookup);
            if ( threads > 1 )
            {
               for (ossim_uint32 nt=1; nt < threads; ++nt)
               {
                  if ( !theThreadEnv->add_thread() )
                  {
                     if (traceDebug())
                     {
                        ossimNotify(ossimNotifyLevel_WARN)
                           << "Unable to create thread!\n";
                     }
                  }
               }
            }
         }
         
         theOpenTileThreadQueue = theThreadEnv->add_queue(NULL,NULL,"open_tile_q");
         
         theCodestream.create(this, theThreadEnv);
         
         if ( theCodestream.exists() )
         {
            //---
            // We have to store things here in this non-const method because
            // NONE of the kakadu methods are const.
            //---
            theMinDwtLevels = theCodestream.get_min_dwt_levels();
            
            theCodestream.set_persistent(); // ????
            theCodestream.enable_restart(); // ????
            
            kdu_dims region_of_interest;
            region_of_interest.pos.x = 0;
            region_of_interest.pos.y = 0;
            region_of_interest.size.x = getNumberOfSamples(0);
            region_of_interest.size.y = getNumberOfLines(0);

            theCodestream.apply_input_restrictions(
               0, // first_component
               0, // max_components (0 = all remaining will appear)
               0, // highest resolution level
               0, // max_layers (0 = all layers retained)
               &region_of_interest, // expanded out to block boundary.
               //KDU_WANT_CODESTREAM_COMPONENTS);
               KDU_WANT_OUTPUT_COMPONENTS);
            
            // Set the scalar:
            theScalarType = theSizRecord.getScalarType();
            if (theScalarType != OSSIM_SCALAR_UNKNOWN)
            {
               //---
               // NOTE: Please leave commented out code for now.
               //---
               // Capture the sub image offset.
               // theSubImageOffset.x = theSizRecord.theXOsiz;
               // theSubImageOffset.y = theSizRecord.theYOsiz;
               
               // Initialize the image rect.
               theImageRect = ossimIrect(0,
                                         0,
                                         theSizRecord.theXsiz-1,
                                         theSizRecord.theYsiz-1);

               // Initialize the cache.
               if (theCacheId != -1)
               {
                  ossimAppFixedTileCache::instance()->deleteCache(theCacheId);
                  theCacheId = -1;
               }
               ossimIpt tileSize(theSizRecord.theXTsiz, theSizRecord.theYTsiz);

               // Stretch to tile boundary for the cache.
               ossimIrect fullImgRect = theImageRect;
               fullImgRect.stretchToTileBoundary(tileSize);
               
               // Set up the tile cache.
               theCacheId = ossimAppFixedTileCache::instance()->
                  newTileCache(fullImgRect, tileSize);

               // Add the sub image rect after the 
               
               // Initialize the tile we will return.
               initializeTile();

               // Call the base complete open to pick up overviews.
               completeOpen();
               
               // We should be good now so set the return result to true.
               result = true;

               if (traceDebug())
               {
                  ossimNotify(ossimNotifyLevel_DEBUG)
                     << "\nSIZ marker segment"
                     << theSizRecord
                     << "theCodestream.get_num_components(false): "
                     << theCodestream.get_num_components(false)
                     << "\ntheCodestream.get_num_components(true): "
                     << theCodestream.get_num_components(true)
                     << "\ntheCodestream.get_bit_depth(0, true): "
                     << theCodestream.get_bit_depth(0, true)
                     << "\ntheCodestream.get_signed(0, true): "
                     << theCodestream.get_signed(0, true)
                     << "\ntheCodestream.get_min_dwt_levels(): "
                     << theCodestream.get_min_dwt_levels()
                     << "\ntheImageRect: " << theImageRect
                     << "\nFull image rect: " << fullImgRect
                     << "\nthreads: " << threads
                     << "\n";
                  
                  vector<ossimDpt> decimations;
                  getDecimationFactors(decimations);
                  for (ossim_uint32 i = 0; i < decimations.size(); ++i)
                  {
                     ossimNotify(ossimNotifyLevel_DEBUG)
                        << theCodestream.get_min_dwt_levels()
                        << "Decimation factor[" << i << "]: "
                        << decimations[i]
                        << "\nsamples[" << i << "]: "
                        << getNumberOfSamples(i)
                        << "\nlines[" << i << "]: "
                        << getNumberOfLines(i)
                        << std::endl;
                     
                  }
               }
            }
               
         } // matches: if ( theCodestream.exists() )
         
      } //  matches: if ( (soc == SOC_MARKER) && (siz == SIZ_MARKER) )
      
   } // matches: if ( theFileStr.good() )
   else
   {
      if(traceDebug())
      {
         ossimNotify(ossimNotifyLevel_DEBUG)
            << MODULE << " ERROR:"
            << "\nCannot open:  " << theImageFile.c_str() << endl;
      }
   }

   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << MODULE << " exit status = " << (result?"true":"false\n")
         << std::endl;
   }

   return result;
}
rspfRefPtr<rspfImageData> rspfImageToPlaneNormalFilter::getTile(
    const rspfIrect& tileRect,
    rspf_uint32 resLevel)
{
    if(!isSourceEnabled()||!theInputConnection)
    {
        return rspfImageSourceFilter::getTile(tileRect, resLevel);
    }

    if(!theTile.valid())
    {
        initialize();
    }

    if(!theTile.valid())
    {
        return rspfImageSourceFilter::getTile(tileRect, resLevel);
    }

    theTile->setImageRectangle(tileRect);

    rspfIrect requestRect(tileRect.ul().x - 1,
                          tileRect.ul().y - 1,
                          tileRect.lr().x + 1,
                          tileRect.lr().y + 1);

    rspfRefPtr<rspfImageData> input =
        theInputConnection->getTile(requestRect, resLevel);

    if(!input||(input->getDataObjectStatus()==RSPF_EMPTY)||!input->getBuf())
    {
        if(tileRect.completely_within(theInputBounds))
        {
            initializeTile();
            theTile->validate();
            return theTile.get();
        }
        theBlankTile->setImageRectangle(tileRect);
        return theBlankTile;
    }

    double oldScaleX = theXScale;
    double oldScaleY = theYScale;

    if(resLevel > 0)
    {
        rspfDpt scaleFactor;
        theInputConnection->getDecimationFactor(resLevel, scaleFactor);

        if(!scaleFactor.hasNans())
        {
            theXScale *= scaleFactor.x;
            theYScale *= scaleFactor.y;
        }
    }

    computeNormals(input, theTile);

    theXScale = oldScaleX;
    theYScale = oldScaleY;

    theTile->validate();

    return theTile;
}