00001 #include "vil_j2k_image.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <NCSFile.h>
00014
00015 #include <vcl_algorithm.h>
00016 #include <vcl_cassert.h>
00017 #include <vcl_cmath.h>
00018 #include <vcl_limits.h>
00019 #include <vcl_cstdlib.h>
00020 #include <vil/vil_memory_chunk.h>
00021 #include <vil/vil_image_view.h>
00022 #include <vil/vil_load.h>
00023 #include <vil/vil_open.h>
00024 #include <vil/vil_new.h>
00025 #include "NCSJPCVilIOStream.h"
00026 #include <NCSTypes.h>
00027
00028
00029
00030
00031 NCSFileBandInfo bandInfo( const vil_pixel_format& vilType )
00032 {
00033 NCSFileBandInfo info;
00034 switch ( vil_pixel_format_component_format( vilType ) )
00035 {
00036 case VIL_PIXEL_FORMAT_UINT_32:{
00037 info.nBits = sizeof(vxl_uint_32)*8;
00038 info.bSigned = vcl_numeric_limits<vxl_uint_32>::is_signed;
00039 info.szDesc = 0;
00040 return info;
00041 }
00042 case VIL_PIXEL_FORMAT_INT_32:{
00043 info.nBits = sizeof(vxl_int_32)*8;
00044 info.bSigned = vcl_numeric_limits<vxl_int_32>::is_signed;
00045 info.szDesc = 0;
00046 return info;
00047 }
00048 case VIL_PIXEL_FORMAT_UINT_16:{
00049 info.nBits = sizeof(vxl_uint_16)*8;
00050 info.bSigned = vcl_numeric_limits<vxl_uint_16>::is_signed;
00051 info.szDesc = 0;
00052 return info;
00053 }
00054 case VIL_PIXEL_FORMAT_INT_16:{
00055 info.nBits = sizeof(vxl_int_16)*8;
00056 info.bSigned = vcl_numeric_limits<vxl_int_16>::is_signed;
00057 info.szDesc = 0;
00058 return info;
00059 }
00060 case VIL_PIXEL_FORMAT_BYTE:{
00061 info.nBits = sizeof(vxl_byte)*8;
00062 info.bSigned = vcl_numeric_limits<vxl_byte>::is_signed;
00063 info.szDesc = 0;
00064 return info;
00065 }
00066 case VIL_PIXEL_FORMAT_SBYTE:{
00067 info.nBits = sizeof(vxl_sbyte)*8;
00068 info.bSigned = vcl_numeric_limits<vxl_sbyte>::is_signed;
00069 info.szDesc = 0;
00070 return info;
00071 }
00072 case VIL_PIXEL_FORMAT_FLOAT:{
00073 info.nBits = sizeof(float)*8;
00074 info.bSigned = vcl_numeric_limits<float>::is_signed;
00075 info.szDesc = 0;
00076 return info;
00077 }
00078 case VIL_PIXEL_FORMAT_DOUBLE:{
00079 info.nBits = sizeof(double)*8;
00080 info.bSigned = vcl_numeric_limits<double>::is_signed;
00081 info.szDesc = 0;
00082 return info;
00083 }
00084 case VIL_PIXEL_FORMAT_BOOL:
00085 case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
00086 case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
00087 case VIL_PIXEL_FORMAT_UINT_64:
00088 case VIL_PIXEL_FORMAT_INT_64:
00089 case VIL_PIXEL_FORMAT_UNKNOWN:
00090 default:{
00091 assert( 0 );
00092 info.nBits = 0; info.bSigned = false; info.szDesc = 0;
00093 return info;
00094 }
00095 }
00096 }
00097
00098
00099
00100
00101 static char const j2k_string[] = "j2k";
00102
00103 char const* vil_j2k_file_format::tag() const
00104 {
00105 return j2k_string;
00106 }
00107
00108 vil_image_resource_sptr vil_j2k_file_format::make_input_image(vil_stream *vs)
00109 {
00110 vil_j2k_image* im = new vil_j2k_image( vs );
00111 if ( !im->is_valid() ) {
00112 delete im;
00113 im = 0;
00114 }
00115 return im;
00116 }
00117
00118
00119 vil_image_resource_sptr
00120 vil_j2k_file_format::make_output_image(vil_stream* vs,
00121 unsigned ni,
00122 unsigned nj,
00123 unsigned nplanes,
00124 enum vil_pixel_format format)
00125 {
00126 vil_j2k_image* j2k_img = new vil_j2k_image(vs, ni, nj, nplanes, format,
00127 compression_ratio_);
00128 if (j2k_img->is_valid())
00129 return static_cast<vil_image_resource*>(j2k_img);
00130 return 0;
00131 }
00132
00133 NCSEcwCellType convertType( const vil_pixel_format& vilType )
00134 {
00135 switch ( vil_pixel_format_component_format( vilType ) ) {
00136 case VIL_PIXEL_FORMAT_UINT_64: return NCSCT_UINT64;
00137 case VIL_PIXEL_FORMAT_INT_64: return NCSCT_INT64;
00138 case VIL_PIXEL_FORMAT_UINT_32: return NCSCT_UINT32;
00139 case VIL_PIXEL_FORMAT_INT_32: return NCSCT_INT32;
00140 case VIL_PIXEL_FORMAT_UINT_16: return NCSCT_UINT16;
00141 case VIL_PIXEL_FORMAT_INT_16: return NCSCT_INT16;
00142 case VIL_PIXEL_FORMAT_BYTE: return NCSCT_UINT8;
00143 case VIL_PIXEL_FORMAT_SBYTE: return NCSCT_INT8;
00144 case VIL_PIXEL_FORMAT_FLOAT: return NCSCT_IEEE4;
00145 case VIL_PIXEL_FORMAT_DOUBLE: return NCSCT_IEEE8;
00146 case VIL_PIXEL_FORMAT_BOOL:
00147 case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
00148 case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
00149 case VIL_PIXEL_FORMAT_UNKNOWN:
00150 default:
00151 assert(0); return NCSCT_UINT8;
00152 }
00153 }
00154
00155
00156
00157 vil_pixel_format convertType( const NCSEcwCellType& ecwType )
00158 {
00159 switch ( ecwType ) {
00160 case NCSCT_UINT64: return VIL_PIXEL_FORMAT_UINT_64;
00161 case NCSCT_INT64: return VIL_PIXEL_FORMAT_INT_64;
00162 case NCSCT_UINT32: return VIL_PIXEL_FORMAT_UINT_32;
00163 case NCSCT_INT32: return VIL_PIXEL_FORMAT_INT_32;
00164 case NCSCT_UINT16: return VIL_PIXEL_FORMAT_UINT_16;
00165 case NCSCT_INT16: return VIL_PIXEL_FORMAT_INT_16;
00166 case NCSCT_UINT8: return VIL_PIXEL_FORMAT_BYTE;
00167 case NCSCT_INT8: return VIL_PIXEL_FORMAT_SBYTE;
00168 case NCSCT_IEEE4: return VIL_PIXEL_FORMAT_FLOAT;
00169 case NCSCT_IEEE8: return VIL_PIXEL_FORMAT_DOUBLE;
00170 default:
00171 assert(0); return VIL_PIXEL_FORMAT_UNKNOWN;
00172 }
00173 }
00174
00175
00176
00177
00178
00179 vil_j2k_image::vil_j2k_image( const vcl_string& fileOrUrl )
00180 : vil_image_resource(),
00181 mFileResource( new CNCSFile() ),
00182 mStr(0),
00183 mMaxLocalDimension( 5000 ),
00184 mMaxRemoteDimension( 640 ),
00185 mRemoteFile( false ),
00186 mFinfo(0),
00187 mBandinfo(0),
00188 line_index_(0)
00189 {
00190 if ( mFileResource->Open( (char*)fileOrUrl.c_str(), false, false ) != NCS_SUCCESS ) {
00191 mFileResource = 0;
00192 return;
00193 }
00194 if ( fileOrUrl.substr( 0, 7 ) == "ecwp://" ||
00195 fileOrUrl.substr( 0, 7 ) == "ECWP://" )
00196 {
00197 mRemoteFile = true;
00198 }
00199 }
00200
00201 vil_j2k_image::vil_j2k_image( vil_stream* is )
00202 : vil_image_resource(),
00203 mFileResource( new CNCSFile() ),
00204 mStr(new CNCSJPCVilIOStream()),
00205 mMaxLocalDimension( 5000 ),
00206 mMaxRemoteDimension( 640 ),
00207 mRemoteFile( false ),
00208 mFinfo(0),
00209 mBandinfo(0),
00210 line_index_(0)
00211 {
00212 mStr->Open( is );
00213
00214 if ( (static_cast<CNCSJP2FileView*>(mFileResource))->Open( mStr ) != NCS_SUCCESS ) {
00215 mFileResource = 0;
00216 return;
00217 }
00218 }
00219
00220 vil_j2k_image::vil_j2k_image( vil_stream* vs, unsigned ni, unsigned nj,
00221 unsigned nplanes, enum vil_pixel_format format,
00222 unsigned compression_ratio)
00223 : vil_image_resource(),
00224 mFileResource( new CNCSFile()),
00225 mStr(new CNCSJPCVilIOStream()),
00226 mMaxLocalDimension( 5000 ),
00227 mMaxRemoteDimension( 640 ),
00228 mRemoteFile( false ),
00229 mFinfo(new NCSFileViewFileInfoEx()),
00230 line_index_(0)
00231 {
00232 mBandinfo = new NCSFileBandInfo[nplanes];
00233 CNCSError Error;
00234 for (unsigned i = 0; i<nplanes; ++i)
00235 mBandinfo[i] = bandInfo(format);
00236
00237
00238 mBandinfo[0].szDesc ="grey";
00239 if (nplanes==3) {
00240 mBandinfo[0].szDesc = "Red";
00241 mBandinfo[1].szDesc = "Green";
00242 mBandinfo[2].szDesc = "Blue";
00243 }
00244 NCSEcwCellType t = convertType(format);
00245 NCSFileViewFileInfoEx finfo=*mFinfo;
00246 finfo.pBands = mBandinfo;
00247 finfo.nSizeX = ni;
00248 finfo.nSizeY = nj;
00249 finfo.nBands = nplanes;
00250 finfo.eCellType = t;
00251 finfo.nCompressionRate = compression_ratio;
00252 finfo.eCellSizeUnits = ECW_CELL_UNITS_METERS;
00253 finfo.fCellIncrementX = 1.0;
00254 finfo.fCellIncrementY = 1.0;
00255 finfo.fOriginX = 0.0;
00256 finfo.fOriginY = 0.0;
00257 finfo.szDatum = "RAW";
00258 finfo.szProjection = "RAW";
00259 finfo.fCWRotationDegrees = 0.0;
00260 if (nplanes ==1)
00261 finfo.eColorSpace = NCSCS_GREYSCALE;
00262 else if (nplanes ==3)
00263 finfo.eColorSpace = NCSCS_sRGB;
00264 else {
00265 delete mFileResource;
00266 mFileResource = 0;
00267 }
00268 Error = mFileResource->SetFileInfo(finfo);
00269 if (Error != NCS_SUCCESS) {
00270 if (mFileResource)
00271 delete mFileResource;
00272 mFileResource = 0;
00273 }
00274 Error = mStr->Open(vs, true);
00275 if (Error != NCS_SUCCESS) {
00276 if (mFileResource)
00277 delete mFileResource;
00278 mFileResource = 0;
00279 }
00280 CNCSJP2FileView* fview = static_cast<CNCSJP2FileView*>(mFileResource);
00281 Error = fview->Open(static_cast<CNCSJPCIOStream*>(mStr));
00282 if (Error != NCS_SUCCESS) {
00283 if (mFileResource)
00284 delete mFileResource;
00285 mFileResource = 0;
00286 return;
00287 }
00288 }
00289
00290 vil_j2k_image::~vil_j2k_image()
00291 {
00292 if ( mFileResource ) {
00293 mFileResource->Close( true );
00294 }
00295 if (mStr)
00296 delete mStr;
00297 if (mBandinfo)
00298 delete mBandinfo;
00299 if (mFinfo)
00300 delete mFinfo;
00301 }
00302
00303 unsigned vil_j2k_image::nplanes() const
00304 {
00305 assert( mFileResource );
00306 return mFileResource->GetFileInfo()->nBands;
00307 }
00308
00309 unsigned vil_j2k_image::ni() const
00310 {
00311 assert( mFileResource );
00312 return mFileResource->GetFileInfo()->nSizeX;
00313 }
00314
00315 unsigned vil_j2k_image::nj() const
00316 {
00317 assert( mFileResource );
00318 return mFileResource->GetFileInfo()->nSizeY;
00319 }
00320
00321 enum vil_pixel_format vil_j2k_image::pixel_format() const
00322 {
00323 assert( mFileResource );
00324 return convertType( mFileResource->GetFileInfo()->eCellType );
00325 }
00326
00327 char const* vil_j2k_image::file_format() const
00328 {
00329 return "j2k";
00330 }
00331
00332 vil_image_view_base_sptr
00333 vil_j2k_image::get_copy_view_decimated(unsigned sample0,
00334 unsigned num_samples,
00335 unsigned line0,
00336 unsigned numLines,
00337 double i_factor,
00338 double j_factor) const
00339 {
00340 return get_copy_view_decimated_by_size(sample0,
00341 num_samples,
00342 line0,
00343 numLines,
00344 (unsigned int)(((double)num_samples)/i_factor),
00345 (unsigned int)(((double)numLines)/j_factor));
00346 }
00347
00348 vil_image_view_base_sptr
00349 vil_j2k_image::get_copy_view_decimated_by_size(unsigned sample0,
00350 unsigned num_samples,
00351 unsigned line0,
00352 unsigned numLines,
00353 unsigned int output_width,
00354 unsigned int output_height) const
00355 {
00356 if ( !( mFileResource ) ||
00357 !( ( sample0 + num_samples - 1 ) < ni() &&
00358 ( line0 + numLines - 1 ) < nj() ) )
00359 {
00360 return 0;
00361 }
00362
00363
00364
00365 INT32 nBands = nplanes();
00366 INT32* bandMap = (INT32*) vcl_malloc(sizeof(UINT32) * nBands );
00367 for ( int i = 0 ; i < nBands ; i++ ) { bandMap[i] = i; }
00368
00369
00370
00371
00372 unsigned int maxDim = mRemoteFile ? mMaxRemoteDimension : mMaxLocalDimension;
00373 if ( output_width > maxDim || output_height > maxDim ) {
00374 unsigned int biggestDim = vcl_max( output_width, output_height );
00375 double zoomFactor = ((double)maxDim) / ((double)biggestDim);
00376 output_width = (unsigned int) ( ((double)output_width) * zoomFactor );
00377 output_height = (unsigned int) ( ((double)output_height) * zoomFactor );
00378 }
00379
00380
00381
00382
00383
00384 NCSError setViewError = mFileResource->SetView( nBands, bandMap, output_width, output_height,
00385 (INT32)sample0, (INT32)line0, (INT32)(sample0+num_samples-1), (INT32)(line0+numLines-1) );
00386 if ( setViewError != NCS_SUCCESS ) {
00387 free( bandMap );
00388 return 0;
00389 }
00390
00391
00392 double bitsPerSample = mFileResource->GetFileInfo()->pBands[0].nBits;
00393 unsigned int bytesPerSample = (unsigned int) vcl_ceil( bitsPerSample / 8.0 );
00394 unsigned int singleBandLineSizeBytes = output_width * bytesPerSample;
00395 unsigned int allBandLineSizeBytes = singleBandLineSizeBytes * nBands;
00396 unsigned int dataPtrSizeBytes = allBandLineSizeBytes * output_height;
00397
00398 vil_memory_chunk_sptr data_ptr = new vil_memory_chunk( dataPtrSizeBytes, convertType( mFileResource->GetFileInfo()->eCellType ) );
00399 void** linePtrPtr = (void**)vcl_malloc( nBands * sizeof( int* ) );
00400
00401 for ( unsigned int currLine = 0 ; currLine < output_height ; currLine++ ) {
00402 for (int currBand = 0 ; currBand < nBands ; currBand++ ) {
00403 linePtrPtr[currBand] = (void*) ( ((char*)data_ptr->data()) + currLine * allBandLineSizeBytes + currBand * singleBandLineSizeBytes );
00404 }
00405 NCSEcwReadStatus readStatus = mFileResource->ReadLineBIL( mFileResource->GetFileInfo()->eCellType, nBands, linePtrPtr, 0);
00406 if ( readStatus != NCSECW_READ_OK ) {
00407 free( bandMap );
00408 free( linePtrPtr );
00409 return 0;
00410 }
00411 }
00412
00413
00414 free( bandMap );
00415 free( linePtrPtr );
00416
00417 vil_image_view_base_sptr view = 0;
00418
00419
00420
00421 switch ( vil_pixel_format_component_format( data_ptr->pixel_format() ) )
00422 {
00423 #define macro( F, T ) \
00424 case F: \
00425 view = new vil_image_view< T > ( data_ptr, reinterpret_cast<T*>(data_ptr->data()), \
00426 output_width, output_height, nBands, 1, output_width*nBands, output_width); \
00427 break
00428 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte );
00429 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte );
00430 macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 );
00431 macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 );
00432 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 );
00433 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 );
00434 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 );
00435 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 );
00436 macro(VIL_PIXEL_FORMAT_BOOL , bool );
00437 #undef macro
00438 default:
00439 vcl_cerr << "Pixel format not supported by ERMapper SDK\n";
00440 assert( 0 );
00441 break;
00442 }
00443
00444 return view;
00445 }
00446
00447 vil_image_view_base_sptr vil_j2k_image::get_copy_view(unsigned sample0,
00448 unsigned num_samples,
00449 unsigned line0,
00450 unsigned numLines ) const
00451 {
00452 return get_copy_view_decimated( sample0, num_samples, line0, numLines, 1.0, 1.0 );
00453 }
00454
00455 void vil_j2k_image::unsetMaxImageDimension( bool remote )
00456 {
00457 #undef max
00458 setMaxImageDimension( vcl_numeric_limits< unsigned int >::max(), remote );
00459 }
00460
00461 void vil_j2k_image::setMaxImageDimension( unsigned int widthOrHeight, bool remote )
00462 {
00463 if ( remote ) {
00464 mMaxRemoteDimension = widthOrHeight;
00465 } else {
00466 mMaxLocalDimension = widthOrHeight;
00467 }
00468 }
00469
00470 vil_image_view_base_sptr vil_j2k_image::s_decode_jpeg_2000( vil_stream* vs,
00471 unsigned i0, unsigned ni,
00472 unsigned j0, unsigned nj,
00473 double i_factor, double j_factor )
00474 {
00475 vil_j2k_image* j2k_image = new vil_j2k_image(vs);
00476
00477
00478 j2k_image->unsetMaxImageDimension();
00479 vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated(i0, ni, j0, nj, i_factor, j_factor);
00480 delete j2k_image;
00481 return view;
00482 }
00483
00484 vil_image_view_base_sptr
00485 vil_j2k_image::s_decode_jpeg_2000_by_size( vil_stream* vs,
00486 unsigned i0, unsigned ni,
00487 unsigned j0, unsigned nj,
00488 unsigned int output_width,
00489 unsigned int output_height )
00490 {
00491 vil_j2k_image* j2k_image = new vil_j2k_image(vs);
00492 vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated_by_size(i0, ni, j0, nj, output_width, output_height);
00493 delete j2k_image;
00494 return view;
00495 }
00496
00497 template < class T >
00498 static bool write_line_BIL(vil_memory_chunk_sptr& chunk,
00499 unsigned ni, unsigned nplanes, unsigned istep,
00500 unsigned planestep, unsigned bytes_per_pixel,
00501 CNCSFile* f_resource, NCSEcwCellType t)
00502 {
00503 T* cdata = reinterpret_cast<T*>(chunk->data());
00504 T** line_ptr = new T*[nplanes];
00505 for (unsigned p = 0; p<nplanes; ++p)
00506 line_ptr[p] = new T[ni*bytes_per_pixel];
00507
00508 for (unsigned p = 0; p<nplanes; ++p) {
00509 T* wline = line_ptr[p];
00510 for (unsigned i = 0; i<ni; ++i) {
00511 *(wline+i) = *(cdata+ i*istep + p*planestep);
00512 }
00513 }
00514 bool good = true;
00515 void ** outbuf = reinterpret_cast<void**>(line_ptr);
00516 CNCSError writeError = f_resource->WriteLineBIL(t, nplanes, outbuf);
00517 if ( writeError != NCS_SUCCESS ) good = false;
00518
00519 for (unsigned p = 0; p<nplanes; ++p)
00520 delete [] line_ptr[p];
00521 delete [] line_ptr;
00522 return good;
00523 }
00524
00525
00526
00527
00528
00529
00530 bool
00531 vil_j2k_image::put_line(const vil_image_view_base& im)
00532 {
00533 if (!mFileResource)
00534 return false;
00535 vil_pixel_format format = this->pixel_format();
00536 unsigned ni = this->ni(), nj = this->nj(), nplanes = this->nplanes();
00537 if (line_index_>=nj) {
00538 mFileResource->Close(true);
00539 if (mFileResource)
00540 delete mFileResource;
00541 mFileResource = 0;
00542 return true;
00543 }
00544 unsigned bytes_per_pixel = 0;
00545 NCSEcwCellType t = convertType(format);
00546 vil_memory_chunk_sptr chunk;
00547
00548
00549
00550 switch ( vil_pixel_format_component_format( format ) )
00551 {
00552 #define macro( F, T )\
00553 case F: {\
00554 bytes_per_pixel = sizeof(T); \
00555 const vil_image_view<T>& view = static_cast<const vil_image_view<T>&>(im); \
00556 chunk = view.memory_chunk(); \
00557 if (!write_line_BIL<T>(chunk, ni, nplanes, view.istep(), view.planestep(),\
00558 bytes_per_pixel, mFileResource, t)) \
00559 return false; \
00560 } \
00561 break
00562 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte );
00563 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte );
00564 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 );
00565 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 );
00566 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 );
00567 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 );
00568 macro(VIL_PIXEL_FORMAT_BOOL , bool );
00569 #undef macro
00570 default:
00571 vcl_cerr << "Pixel format not supported by ERMapper SDK\n";
00572 assert( 0 );
00573 break;
00574 }
00575 ++line_index_;
00576 return true;
00577 }
00578
00579
00580
00581
00582 bool vil_j2k_image::
00583 put_view(const vil_image_view_base& im)
00584 {
00585 if (!this->view_fits(im, 0, 0))
00586 return false;
00587 if (!mFileResource)
00588 return false;
00589 unsigned ni= im.ni(), nj = im.nj();
00590 vil_image_resource_sptr mem_res =
00591 vil_new_image_resource_of_view(im);
00592 vil_image_view_base_sptr view;
00593 for (unsigned j = 0; j<nj; ++j) {
00594 view = mem_res->get_copy_view(0, ni, j, 1);
00595 if (!this->put_line(*view)) return false;
00596 }
00597 return true;
00598 }
00599
00600
00601 bool vil_j2k_image::
00602 view_fits(const vil_image_view_base& im, unsigned i0, unsigned j0)
00603 {
00604 unsigned ni_view = im.ni(), nj_view = im.nj(), nplanes_view = im.nplanes();
00605 return i0+1 < ni_view
00606 && j0+1 < nj_view
00607 && ni_view <= this->ni()
00608 && nj_view <= this->nj()
00609 && nplanes_view <= this->nplanes();
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 bool vil_j2k_image::s_encode_jpeg2000(vil_stream* vs,
00619 const char* out_filename,
00620 unsigned compression_ratio,
00621 unsigned num_lines_block,
00622 bool verbose)
00623 {
00624 vil_image_resource_sptr in_res = vil_load_image_resource_raw(vs);
00625 if (!in_res)
00626 return false;
00627 unsigned ni = in_res->ni(), nj = in_res->nj(), nplanes = in_res->nplanes();
00628 vil_pixel_format format = in_res->pixel_format();
00629 vil_stream* os = vil_open(out_filename, "w");
00630 if (!vs) return false;
00631 vil_j2k_file_format fmt;
00632 fmt.set_compression_ratio(compression_ratio);
00633 vil_image_resource_sptr res = fmt.make_output_image(os, ni, nj, nplanes,
00634 format);
00635 if (!res) return false;
00636 vil_j2k_image* j2k_img = reinterpret_cast<vil_j2k_image*>(res.ptr());
00637
00638
00639 unsigned n_blocks = nj/num_lines_block;
00640 unsigned jb = 0;
00641 for (unsigned b = 0; b<n_blocks; b++, jb += num_lines_block)
00642 {
00643
00644 vil_image_view_base_sptr block_view = in_res->get_view(0, ni, jb, num_lines_block);
00645 if (!block_view) return false;
00646
00647
00648 vil_image_resource_sptr block_res =
00649 vil_new_image_resource_of_view(*block_view);
00650
00651
00652 for (unsigned j = 0; j<num_lines_block; ++j) {
00653 vil_image_view_base_sptr line_view =
00654 block_res->get_copy_view(0, ni, j, 1);
00655 if (!j2k_img->put_line(*line_view)) return false;
00656 if (verbose)
00657 if (j%100 == 0)
00658 vcl_cout << '.';
00659 }
00660 }
00661
00662 unsigned remaining_lines = nj-jb;
00663 if (remaining_lines) {
00664 vil_image_view_base_sptr residual_view =
00665 in_res->get_view(0, ni, jb, remaining_lines);
00666 vil_image_resource_sptr residual_res =
00667 vil_new_image_resource_of_view(*residual_view);
00668 vil_image_view_base_sptr view;
00669 for (unsigned j = 0; j<remaining_lines; ++j) {
00670 view = residual_res->get_copy_view(0, ni, j, 1);
00671 if (!j2k_img->put_line(*view)) return false;
00672 if (verbose)
00673 if (j%100 == 0)
00674 vcl_cout << '.';
00675 }
00676 }
00677 if (verbose) vcl_cout << '\n';
00678 return true;
00679 }
00680
00681 bool vil_j2k_image::s_encode_jpeg2000(const char* in_filename,
00682 const char* out_filename,
00683 unsigned compression_ratio,
00684 unsigned num_lines_block,
00685 bool verbose )
00686 {
00687 vil_stream* vs = vil_open(in_filename);
00688 vs->ref();
00689 bool success =
00690 vil_j2k_image::s_encode_jpeg2000(vs, out_filename,
00691 compression_ratio,
00692 num_lines_block,
00693 verbose);
00694 vs->unref();
00695 return success;
00696 }
00697