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) ®ion_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; }