Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_j2k_image.cxx

Go to the documentation of this file.
00001 // vil_j2k: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
00002 // Stellar Science Ltd. Co. (stellarscience.com) for
00003 // Air Force Research Laboratory, 2005.
00004 
00005 #include "vil_j2k_image.h"
00006 
00007 #include <NCSFile.h>
00008 
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cassert.h>
00011 #include <vcl_cmath.h> // for ceil()
00012 #include <vcl_limits.h>
00013 #include <vil/vil_memory_chunk.h>
00014 #include <vil/vil_image_view.h>
00015 
00016 #include "NCSJPCVilIOStream.h"
00017 #include <NCSTypes.h>
00018 
00019 //--------------------------------------------------------------------------------
00020 // class vil_j2k_file_format
00021 
00022 static char const j2k_string[] = "j2k";
00023 
00024 char const* vil_j2k_file_format::tag() const
00025 {
00026   return j2k_string;
00027 }
00028 
00029 vil_image_resource_sptr  vil_j2k_file_format::make_input_image(vil_stream *vs)
00030 {
00031   vil_j2k_image* im = new vil_j2k_image( vs );
00032   if ( !im->is_valid() ) {
00033     delete im;
00034     im = 0;
00035   }
00036   return im;
00037 }
00038 
00039 vil_image_resource_sptr
00040   vil_j2k_file_format::make_output_image(vil_stream* /*vs*/,
00041                                           unsigned /*nx*/,
00042                                           unsigned /*ny*/,
00043                                           unsigned /*nplanes*/,
00044                                           enum vil_pixel_format /*format*/)
00045 {
00046   //write not supported
00047   return 0;
00048 }
00049 
00050 NCSEcwCellType convertType( const vil_pixel_format& vilType )
00051 {
00052   switch ( vil_pixel_format_component_format( vilType ) ) {
00053   case VIL_PIXEL_FORMAT_UINT_64: return NCSCT_UINT64;
00054   case VIL_PIXEL_FORMAT_INT_64: return NCSCT_INT64;
00055   case VIL_PIXEL_FORMAT_UINT_32: return NCSCT_UINT32;
00056   case VIL_PIXEL_FORMAT_INT_32: return NCSCT_INT32;
00057   case VIL_PIXEL_FORMAT_UINT_16: return NCSCT_UINT16;
00058   case VIL_PIXEL_FORMAT_INT_16: return NCSCT_INT16;
00059   case VIL_PIXEL_FORMAT_BYTE: return NCSCT_UINT8;
00060   case VIL_PIXEL_FORMAT_SBYTE: return NCSCT_INT8;
00061   case VIL_PIXEL_FORMAT_FLOAT: return NCSCT_IEEE4;
00062   case VIL_PIXEL_FORMAT_DOUBLE: return NCSCT_IEEE8;
00063   case VIL_PIXEL_FORMAT_BOOL:
00064   case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
00065   case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
00066   case VIL_PIXEL_FORMAT_UNKNOWN:
00067   default:
00068     assert( 0 );
00069     return NCSCT_UINT8;
00070   }
00071 }
00072 
00073 vil_pixel_format convertType( const NCSEcwCellType& ecwType )
00074 {
00075   switch ( ecwType ) {
00076   case NCSCT_UINT64: return VIL_PIXEL_FORMAT_UINT_64;
00077   case NCSCT_INT64: return VIL_PIXEL_FORMAT_INT_64;
00078   case NCSCT_UINT32: return VIL_PIXEL_FORMAT_UINT_32;
00079   case NCSCT_INT32: return VIL_PIXEL_FORMAT_INT_32;
00080   case NCSCT_UINT16: return VIL_PIXEL_FORMAT_UINT_16;
00081   case NCSCT_INT16: return VIL_PIXEL_FORMAT_INT_16;
00082   case NCSCT_UINT8: return VIL_PIXEL_FORMAT_BYTE;
00083   case NCSCT_INT8: return VIL_PIXEL_FORMAT_SBYTE;
00084   case NCSCT_IEEE4: return VIL_PIXEL_FORMAT_FLOAT;
00085   case NCSCT_IEEE8: return VIL_PIXEL_FORMAT_DOUBLE;
00086   default:
00087     assert( 0 );
00088     return VIL_PIXEL_FORMAT_UNKNOWN;
00089   }
00090 }
00091 
00092 ////////////////////////////////////////////////////
00093 //                vil_j2k_image
00094 ////////////////////////////////////////////////////
00095 
00096 vil_j2k_image::vil_j2k_image( const vcl_string& fileOrUrl )
00097   : vil_image_resource(),
00098     mFileResource( 0 ),
00099     mMaxLocalDimension( 5000 ), //default value
00100     mMaxRemoteDimension( 640 ), //default value
00101     mRemoteFile( false )
00102 {
00103   mFileResource = new CNCSFile();
00104   if ( mFileResource->Open( (char*)fileOrUrl.c_str(), false, false ) != NCS_SUCCESS ) {
00105     mFileResource = 0;
00106     return;
00107   }
00108   if ( fileOrUrl.substr( 0, 7 ) == "ecwp://" ||
00109       fileOrUrl.substr( 0, 7 ) == "ECWP://" )
00110   {
00111     mRemoteFile = true;
00112   }
00113 }
00114 
00115 vil_j2k_image::vil_j2k_image( vil_stream* is )
00116   : vil_image_resource(),
00117     mFileResource( 0 ),
00118     mMaxLocalDimension( 5000 ), //default value
00119     mMaxRemoteDimension( 640 ), //default value
00120     mRemoteFile( false )
00121 {
00122   mFileResource = new CNCSFile();
00123   CNCSJPCVilIOStream* cstr = new CNCSJPCVilIOStream();
00124   cstr->Open( is );
00125 
00126   if ( (static_cast<CNCSJP2FileView*>(mFileResource))->Open( cstr ) != NCS_SUCCESS ) {
00127     mFileResource = 0;
00128     return;
00129   }
00130 }
00131 
00132 vil_j2k_image::~vil_j2k_image()
00133 {
00134   if ( mFileResource ){
00135     mFileResource->Close( true );
00136   }
00137 }
00138 
00139 unsigned vil_j2k_image::nplanes() const
00140 {
00141   assert( mFileResource );
00142   return mFileResource->GetFileInfo()->nBands;
00143 }
00144 
00145 unsigned vil_j2k_image::ni() const
00146 {
00147   assert( mFileResource );
00148   return mFileResource->GetFileInfo()->nSizeX;
00149 }
00150 
00151 unsigned vil_j2k_image::nj() const
00152 {
00153   assert( mFileResource );
00154   return mFileResource->GetFileInfo()->nSizeY;
00155 }
00156 
00157 enum vil_pixel_format vil_j2k_image::pixel_format() const
00158 {
00159   assert( mFileResource );
00160   return convertType( mFileResource->GetFileInfo()->eCellType );
00161 }
00162 
00163 vil_image_view_base_sptr 
00164 vil_j2k_image::get_copy_view_decimated(unsigned sample0,
00165                                        unsigned num_samples,
00166                                        unsigned line0,
00167                                        unsigned numLines,
00168                                        double i_factor,
00169                                        double j_factor) const
00170 {
00171   return get_copy_view_decimated_by_size(sample0,
00172                                          num_samples,
00173                                          line0,
00174                                          numLines,
00175                                          (unsigned int)(((double)num_samples)/i_factor),
00176                                          (unsigned int)(((double)numLines)/j_factor));
00177 }
00178 
00179 vil_image_view_base_sptr 
00180 vil_j2k_image::get_copy_view_decimated_by_size(unsigned sample0,
00181                                                unsigned num_samples,
00182                                                unsigned line0,
00183                                                unsigned numLines,
00184                                                unsigned int output_width,
00185                                                unsigned int output_height) const
00186 {
00187   if ( !( mFileResource ) ||
00188       !( ( sample0 + num_samples - 1 ) < ni() &&
00189          ( line0 + numLines - 1 ) < nj() ) )
00190   {
00191     return 0;
00192   }
00193 
00194   //we want all bands mapped in the same order as they come in the input file
00195   //eg. bandMap = {0,1,2,3...nBands}
00196   INT32 nBands = nplanes();
00197   INT32* bandMap = (INT32*) malloc(sizeof(UINT32) * nBands );
00198   for ( int i = 0 ; i < nBands ; i++ ) { bandMap[i] = i; }
00199 
00200   //this guards us from returning an image that is too big for the computer's memory
00201   //(or would take too long to download in the remote case).
00202   //We don't want infinite hangs or application crashes.
00203   unsigned int maxDim = mRemoteFile ? mMaxRemoteDimension : mMaxLocalDimension;
00204   if ( output_width > maxDim || output_height > maxDim ){
00205     unsigned int biggestDim = vcl_max( output_width, output_height );
00206     double zoomFactor = ((double)maxDim) / ((double)biggestDim);
00207     output_width  = (unsigned int) ( ((double)output_width)  * zoomFactor );
00208     output_height = (unsigned int) ( ((double)output_height) * zoomFactor );
00209   }
00210 
00211   //set the view to be that specified by the function's input parameters
00212   //note that we don't want ECW to do any scaling for us.  That's why
00213   //the box created by (sample0,line0) and (sample0+num_samples-1,line0+numLines-1) is made to be exactly num_samplesXnumLines.
00214 
00215   NCSError setViewError = mFileResource->SetView( nBands, bandMap, output_width, output_height,
00216                                                   (INT32)sample0, (INT32)line0, (INT32)(sample0+num_samples-1), (INT32)(line0+numLines-1) );
00217   if ( setViewError != NCS_SUCCESS ){
00218     free( bandMap );
00219     return 0;
00220   }
00221 
00222   //number of samples times the bytes per sample in each band
00223   double bitsPerSample                 = mFileResource->GetFileInfo()->pBands[0].nBits;
00224   unsigned int bytesPerSample          = (unsigned int) vcl_ceil( bitsPerSample / 8.0 );
00225   unsigned int singleBandLineSizeBytes = output_width * bytesPerSample;
00226   unsigned int allBandLineSizeBytes    = singleBandLineSizeBytes * nBands;
00227   unsigned int dataPtrSizeBytes        = allBandLineSizeBytes * output_height;
00228   //void* data_ptr = malloc( dataPtrSizeBytes );
00229   vil_memory_chunk_sptr data_ptr = new vil_memory_chunk( dataPtrSizeBytes, convertType( mFileResource->GetFileInfo()->eCellType ) );
00230   void** linePtrPtr = (void**)malloc( nBands * sizeof( int* /*all pointers have same size, so eg char* would work too*/ ) );
00231   //now read all the lines that we want
00232   for ( unsigned int currLine = 0 ; currLine < output_height ; currLine++ ){
00233     for (int currBand = 0 ; currBand < nBands ; currBand++ ){
00234       linePtrPtr[currBand] = (void*) ( ((char*)data_ptr->data()) + currLine * allBandLineSizeBytes + currBand * singleBandLineSizeBytes );
00235     }
00236     NCSEcwReadStatus readStatus = mFileResource->ReadLineBIL( mFileResource->GetFileInfo()->eCellType, nBands, linePtrPtr, 0);
00237     if ( readStatus != NCSECW_READ_OK ){
00238       free( bandMap );
00239       free( linePtrPtr );
00240       return 0;
00241     }
00242   }
00243 
00244   //free our temp resources
00245   free( bandMap );
00246   free( linePtrPtr );
00247 
00248   vil_image_view_base_sptr view = 0;
00249   //now create our vil_image_view
00250   switch ( vil_pixel_format_component_format( data_ptr->pixel_format() ) )
00251   {
00252 #define macro( F, T ) \
00253   case F: \
00254     view = new vil_image_view< T > ( data_ptr, reinterpret_cast<T*>(data_ptr->data()), \
00255                                      output_width, output_height, nBands, 1, output_width*nBands, output_width); \
00256     break
00257   macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte );
00258   macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte );
00259   macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 );
00260   macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 );
00261   macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 );
00262   macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 );
00263   macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 );
00264   macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 );
00265   macro(VIL_PIXEL_FORMAT_BOOL , bool );
00266   macro(VIL_PIXEL_FORMAT_FLOAT , float );
00267   macro(VIL_PIXEL_FORMAT_DOUBLE , double );
00268 #undef macro
00269   default:
00270     assert( 0 );
00271     //"Unknown vil data type." );
00272     break;
00273   }
00274 
00275   return view;
00276 }
00277 
00278 vil_image_view_base_sptr vil_j2k_image::get_copy_view(unsigned sample0,
00279                                                       unsigned num_samples,
00280                                                       unsigned line0,
00281                                                       unsigned numLines ) const
00282 {
00283   return get_copy_view_decimated( sample0, num_samples, line0, numLines, 1.0, 1.0 );
00284 }
00285 
00286 void vil_j2k_image::unsetMaxImageDimension( bool remote )
00287 {
00288 #undef max
00289   setMaxImageDimension( vcl_numeric_limits< unsigned int >::max(), remote );
00290 }
00291 
00292 void vil_j2k_image::setMaxImageDimension( unsigned int widthOrHeight, bool remote )
00293 {
00294   if ( remote ) {
00295     mMaxRemoteDimension = widthOrHeight;
00296   } else {
00297     mMaxLocalDimension = widthOrHeight;
00298   }
00299 }
00300 
00301 vil_image_view_base_sptr vil_j2k_image::s_decode_jpeg_2000( vil_stream* vs,
00302                                                             unsigned i0, unsigned ni,
00303                                                             unsigned j0, unsigned nj,
00304                                                             double i_factor, double j_factor )
00305 {
00306   vil_j2k_image* j2k_image = new vil_j2k_image(vs);
00307   vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated(i0, ni, j0, nj, i_factor, j_factor);
00308   delete j2k_image;
00309   return view;
00310 }
00311 
00312 vil_image_view_base_sptr 
00313 vil_j2k_image::s_decode_jpeg_2000_by_size( vil_stream* vs,
00314                                            unsigned i0, unsigned ni,
00315                                            unsigned j0, unsigned nj,
00316                                            unsigned int output_width, 
00317                                            unsigned int output_height )
00318 {
00319   vil_j2k_image* j2k_image = new vil_j2k_image(vs);
00320   vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated_by_size(i0, ni, j0, nj, output_width, output_height);
00321   delete j2k_image;
00322   return view;
00323 }

Generated on Thu Jan 10 14:39:59 2008 for core/vil by  doxygen 1.4.4