void ossimImageSourceSequencer::setAreaOfInterest(const ossimIrect& areaOfInterest)
{
   if(areaOfInterest.hasNans())
   {
      theAreaOfInterest.makeNan();
      theNumberOfTilesHorizontal = 0;
      theNumberOfTilesVertical   = 0;
   }

   // let's round it to the nearest pixel value before setting it.
   theAreaOfInterest = areaOfInterest;
   updateTileDimensions();
}
예제 #2
0
bool ossim::opj_decode( std::ifstream* in,
                        const ossimIrect& rect,
                        ossim_uint32 resLevel,
                        ossim_int32 format, // OPJ_CODEC_FORMAT
                        std::streamoff fileOffset,
                        ossimImageData* tile)
{
   static const char MODULE[] = "ossimOpjDecoder::decode";

   bool status = false;

   if ( traceDebug() )
   {
      ossimNotify(ossimNotifyLevel_DEBUG)
         << MODULE << "entered...\nrect: " << rect
         << "\nresLevel: " << resLevel << std::endl;
   }
   
   // Need to check for NAN in rect
   if ( in && tile && !rect.hasNans())
   {
      in->seekg( fileOffset, std::ios_base::beg );

      opj_dparameters_t param;
      opj_codec_t*      codec = 0;
      opj_image_t*      image = 0;;
      opj_stream_t*     stream = 0;

      opj_user_istream* userStream = new opj_user_istream();
      userStream->m_str = in;
      userStream->m_offset = fileOffset;

      /* Set the length to avoid an assert */
      in->seekg(0, std::ios_base::end);

      // Fix: length must be passed in for nift blocks.
      userStream->m_length = in->tellg();

      // Set back to front:
      in->clear();
      in->seekg(fileOffset, std::ios_base::beg);
      
      stream = opj_stream_default_create(OPJ_TRUE);
      if (!stream)
      {
         opj_stream_destroy(stream);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_setup_decoder failed!";
         throw ossimException(errMsg);
      }
      
      opj_stream_set_read_function(stream, ossim_opj_istream_read);
      opj_stream_set_skip_function(stream, ossim_opj_istream_skip);
      opj_stream_set_seek_function(stream, ossim_opj_istream_seek);

      // Fix: length must be passed in for nift blocks.
      opj_stream_set_user_data_length(stream, userStream->m_length);
      
      opj_stream_set_user_data(stream, userStream,
                               ossim_opj_free_user_istream_data);

      opj_stream_set_user_data_length(stream, userStream->m_length);

      
      /* Set the default decoding parameters */
      opj_set_default_decoder_parameters(&param);

      param.decod_format = format;

      /** you may here add custom decoding parameters */
      /* do not use layer decoding limitations */
      param.cp_layer = 0;

      /* do not use resolutions reductions */
      param.cp_reduce = resLevel;

      codec = opj_create_decompress( (CODEC_FORMAT)format );

      // catch events using our callbacks and give a local context
      //opj_set_info_handler   (codec, ossim::opj_info_callback,   00);
      opj_set_info_handler   (codec, NULL,   00);
      opj_set_warning_handler(codec, ossim::opj_warning_callback,00);
      opj_set_error_handler  (codec, ossim::opj_error_callback,  00);

      // Setup the decoder decoding parameters using user parameters
      if ( opj_setup_decoder(codec, &param) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_setup_decoder failed!";
         throw ossimException(errMsg);
      }

      // Read the main header of the codestream and if necessary the JP2 boxes.
      if ( opj_read_header(stream, codec, &image) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);         
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_read_header failed!";
         throw ossimException(errMsg);
      }

      // tmp drb:
      // opj_stream_destroy(stream);
      // return;
      
      if ( opj_set_decoded_resolution_factor(codec, resLevel) == false)
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);
         std::string errMsg = MODULE;
         errMsg += " ERROR:  opj_set_decoded_resolution_factor failed!";
         throw ossimException(errMsg);
      }

      //ossim_float32 res = resLevel;
      ossimIrect resRect = rect * (1 << resLevel);

      //std::cout << "resRect.ul(): " << resRect.ul()
      //          << "\nresRect.lr(): " << resRect.lr()
      //          << std::endl;

//      if ( opj_set_decode_area(codec, image, rect.ul().x, rect.ul().y,
//                               rect.lr().x+1, rect.lr().y+1) == false )
      if ( opj_set_decode_area(codec, image, resRect.ul().x, resRect.ul().y,
                               resRect.lr().x+1, resRect.lr().y+1) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_set_decode_area failed!";
         throw ossimException(errMsg);
      }

      // Get the decoded image:
      if ( opj_decode(codec, stream, image) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_decode failed!";
         throw ossimException(errMsg);
      }
      
      // ossim::print(std::cout, *image);
      if(image->icc_profile_buf) {
#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2)
          color_apply_icc_profile(image); /* FIXME */
#endif
          free(image->icc_profile_buf);
          image->icc_profile_buf = NULL; image->icc_profile_len = 0;
      }

      status = ossim::copyOpjImage(image, tile);
      
#if 0
      ossim_uint32 tile_index      = 0;
      ossim_uint32 data_size       = 0;
      ossim_int32  current_tile_x0 = 0;
      ossim_int32  current_tile_y0 = 0;
      ossim_int32  current_tile_x1 = 0;
      ossim_int32  current_tile_y1 = 0;
      ossim_uint32 nb_comps        = 0;
      OPJ_BOOL go_on = 1;

      if ( opj_read_tile_header( codec,
                                 stream,
                                 &tile_index,
                                 &data_size,
                                 &current_tile_x0,
                                 &current_tile_y0,
                                 &current_tile_x1,
                                 &current_tile_y1,
                                 &nb_comps,
                                 &go_on) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_read_tile_header failed!";
         throw ossimException(errMsg);
      }
#endif

#if 0
      std::cout << "tile_index:      " << tile_index
                << "\ndata_size:       " << data_size
                << "\ncurrent_tile_x0: " << current_tile_x0
                << "\ncurrent_tile_y0: " << current_tile_y0
                << "\ncurrent_tile_x1: " << current_tile_x1
                << "\ncurrent_tile_y1: " << current_tile_y1
                << "\nnb_comps:        " << nb_comps
                << std::endl;
#endif

#if 0
      if ( opj_decode_tile_data(codec, tile_index,l_data,l_data_size,l_stream) == false)
      {
         opj_stream_destroy(l_stream);
         opj_destroy_codec(l_codec);
         opj_image_destroy(l_image);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_read_tile_header failed!";
         throw ossimException(errMsg);
      }
#endif

#if 0
      
      if (opj_end_decompress(codec,stream) == false )
      {
         opj_stream_destroy(stream);
         opj_destroy_codec(codec);
         opj_image_destroy(image);
         std::string errMsg = MODULE;
         errMsg += " ERROR: opj_end_decompress failed!";
         throw ossimException(errMsg);
      } 

#endif
      
      /* Free memory */
      opj_stream_destroy(stream);
      opj_destroy_codec(codec);
      opj_image_destroy(image);

      // Tmp drb:
      if ( in->eof() )
      {
         in->clear();
      }
      in->seekg(fileOffset, std::ios_base::beg );
      
   } // Matches: if ( in && tile )

   return status;
   
} // End: ossim::opj_decode( ... )