vil_j2k_image.cxx
Go to the documentation of this file.
1 #include <algorithm>
2 #include <cmath>
3 #include <limits>
4 #include <cstdlib>
5 #include "vil_j2k_image.h"
6 //:
7 // \file
8 // vil_j2k: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
9 // Stellar Science Ltd. Co. (stellarscience.com) for
10 // Air Force Research Laboratory, 2005.
11 // Write capability added by J. Mundy, April 2009
12 // Do not remove the following notice
13 // Modifications approved for public Release, distribution unlimited
14 // DISTAR Case 14074
15 //
16 
17 #include <NCSFile.h>
18 
19 #include <cassert>
20 #ifdef _MSC_VER
21 # include <vcl_msvc_warnings.h>
22 #endif
23 #include <vil/vil_memory_chunk.h>
24 #include <vil/vil_image_view.h>
25 #include <vil/vil_load.h>
26 #include <vil/vil_open.h>
27 #include <vil/vil_new.h>
28 #include "NCSJPCVilIOStream.h"
29 #include <NCSTypes.h>
30 
31 // Fix me - need to add UINT64 and INT64 - JLM
32 // Also note, float and double are defined but not handled by SDK 3.3
33 // they are reinterpreted as INT32 and INT64
34 NCSFileBandInfo bandInfo( const vil_pixel_format& vilType )
35 {
36  NCSFileBandInfo info;
37  switch ( vil_pixel_format_component_format( vilType ) )
38  {
40  info.nBits = sizeof(vxl_uint_32)*8;
41  info.bSigned = std::numeric_limits<vxl_uint_32>::is_signed;
42  info.szDesc = 0;
43  return info;
44  }
46  info.nBits = sizeof(vxl_int_32)*8;
47  info.bSigned = std::numeric_limits<vxl_int_32>::is_signed;
48  info.szDesc = 0;
49  return info;
50  }
52  info.nBits = sizeof(vxl_uint_16)*8;
53  info.bSigned = std::numeric_limits<vxl_uint_16>::is_signed;
54  info.szDesc = 0;
55  return info;
56  }
58  info.nBits = sizeof(vxl_int_16)*8;
59  info.bSigned = std::numeric_limits<vxl_int_16>::is_signed;
60  info.szDesc = 0;
61  return info;
62  }
64  info.nBits = sizeof(vxl_byte)*8;
65  info.bSigned = std::numeric_limits<vxl_byte>::is_signed;
66  info.szDesc = 0;
67  return info;
68  }
70  info.nBits = sizeof(vxl_sbyte)*8;
71  info.bSigned = std::numeric_limits<vxl_sbyte>::is_signed;
72  info.szDesc = 0;
73  return info;
74  }
76  info.nBits = sizeof(float)*8;
77  info.bSigned = std::numeric_limits<float>::is_signed;
78  info.szDesc = 0;
79  return info;
80  }
82  info.nBits = sizeof(double)*8;
83  info.bSigned = std::numeric_limits<double>::is_signed;
84  info.szDesc = 0;
85  return info;
86  }
90  case VIL_PIXEL_FORMAT_UINT_64:
91  case VIL_PIXEL_FORMAT_INT_64:
93  default:{
94  assert( 0 );
95  info.nBits = 0; info.bSigned = false; info.szDesc = 0;
96  return info;
97  }
98  }
99 }
100 
101 //--------------------------------------------------------------------------------
102 // class vil_j2k_file_format
103 
104 static char const j2k_string[] = "j2k";
105 
106 char const* vil_j2k_file_format::tag() const
107 {
108  return j2k_string;
109 }
110 
112 {
113  vil_j2k_image* im = new vil_j2k_image( vs );
114  if ( !im->is_valid() ) {
115  delete im;
116  im = 0;
117  }
118  return im;
119 }
120 
121 
124  unsigned ni,
125  unsigned nj,
126  unsigned nplanes,
127  enum vil_pixel_format format)
128 {
129  vil_j2k_image* j2k_img = new vil_j2k_image(vs, ni, nj, nplanes, format,
131  if (j2k_img->is_valid())
132  return static_cast<vil_image_resource*>(j2k_img);
133  return 0;
134 }
135 
136 NCSEcwCellType convertType( const vil_pixel_format& vilType )
137 {
138  switch ( vil_pixel_format_component_format( vilType ) ) {
139  case VIL_PIXEL_FORMAT_UINT_64: return NCSCT_UINT64;
140  case VIL_PIXEL_FORMAT_INT_64: return NCSCT_INT64;
141  case VIL_PIXEL_FORMAT_UINT_32: return NCSCT_UINT32;
142  case VIL_PIXEL_FORMAT_INT_32: return NCSCT_INT32;
143  case VIL_PIXEL_FORMAT_UINT_16: return NCSCT_UINT16;
144  case VIL_PIXEL_FORMAT_INT_16: return NCSCT_INT16;
145  case VIL_PIXEL_FORMAT_BYTE: return NCSCT_UINT8;
146  case VIL_PIXEL_FORMAT_SBYTE: return NCSCT_INT8;
147  case VIL_PIXEL_FORMAT_FLOAT: return NCSCT_IEEE4;
148  case VIL_PIXEL_FORMAT_DOUBLE: return NCSCT_IEEE8;
153  default:
154  assert(0); return NCSCT_UINT8;
155  }
156 }
157 
158 // Note the J2K SDK defines IEEE4 and IEEE8 but they are not
159 // handled as float or double, they are reinterpreted as INT32 and INT64
160 vil_pixel_format convertType( const NCSEcwCellType& ecwType )
161 {
162  switch ( ecwType ) {
163  case NCSCT_UINT64: return VIL_PIXEL_FORMAT_UINT_64;
164  case NCSCT_INT64: return VIL_PIXEL_FORMAT_INT_64;
165  case NCSCT_UINT32: return VIL_PIXEL_FORMAT_UINT_32;
166  case NCSCT_INT32: return VIL_PIXEL_FORMAT_INT_32;
167  case NCSCT_UINT16: return VIL_PIXEL_FORMAT_UINT_16;
168  case NCSCT_INT16: return VIL_PIXEL_FORMAT_INT_16;
169  case NCSCT_UINT8: return VIL_PIXEL_FORMAT_BYTE;
170  case NCSCT_INT8: return VIL_PIXEL_FORMAT_SBYTE;
171  case NCSCT_IEEE4: return VIL_PIXEL_FORMAT_FLOAT;
172  case NCSCT_IEEE8: return VIL_PIXEL_FORMAT_DOUBLE;
173  default:
174  assert(0); return VIL_PIXEL_FORMAT_UNKNOWN;
175  }
176 }
177 
178 ////////////////////////////////////////////////////
179 // vil_j2k_image
180 ////////////////////////////////////////////////////
181 
182 vil_j2k_image::vil_j2k_image( const std::string& fileOrUrl )
183  : vil_image_resource(),
184  mFileResource( new CNCSFile() ),
185  mStr(0),
186  mMaxLocalDimension( 5000 ), //default value
187  mMaxRemoteDimension( 640 ), //default value
188  mRemoteFile( false ),
189  mFinfo(0),
190  mBandinfo(0),
191  line_index_(0)
192 {
193  if ( mFileResource->Open( (char*)fileOrUrl.c_str(), false, false ) != NCS_SUCCESS ) {
194  mFileResource = 0;
195  return;
196  }
197  if ( fileOrUrl.substr( 0, 7 ) == "ecwp://" ||
198  fileOrUrl.substr( 0, 7 ) == "ECWP://" )
199  {
200  mRemoteFile = true;
201  }
202 }
203 
205  : vil_image_resource(),
206  mFileResource( new CNCSFile() ),
207  mStr(new CNCSJPCVilIOStream()),
208  mMaxLocalDimension( 5000 ), //default value
209  mMaxRemoteDimension( 640 ), //default value
210  mRemoteFile( false ),
211  mFinfo(0),
212  mBandinfo(0),
213  line_index_(0)
214 {
215  mStr->Open( is );
216 
217  if ( (static_cast<CNCSJP2FileView*>(mFileResource))->Open( mStr ) != NCS_SUCCESS ) {
218  mFileResource = 0;
219  return;
220  }
221 }
222 
223 vil_j2k_image::vil_j2k_image( vil_stream* vs, unsigned ni, unsigned nj,
224  unsigned nplanes, enum vil_pixel_format format,
225  unsigned compression_ratio)
226  : vil_image_resource(),
227  mFileResource( new CNCSFile()),
228  mStr(new CNCSJPCVilIOStream()),
229  mMaxLocalDimension( 5000 ), //default value
230  mMaxRemoteDimension( 640 ), //default value
231  mRemoteFile( false ),
232  mFinfo(new NCSFileViewFileInfoEx()),
233  line_index_(0)
234 {
235  mBandinfo = new NCSFileBandInfo[nplanes];
236  CNCSError Error;
237  for (unsigned i = 0; i<nplanes; ++i)
238  mBandinfo[i] = bandInfo(format);
239 
240  //String names for each band, should specialize according to color space
241  mBandinfo[0].szDesc ="grey";
242  if (nplanes==3) {
243  mBandinfo[0].szDesc = "Red";
244  mBandinfo[1].szDesc = "Green";
245  mBandinfo[2].szDesc = "Blue";
246  }
247  NCSEcwCellType t = convertType(format);
248  NCSFileViewFileInfoEx finfo=*mFinfo;
249  finfo.pBands = mBandinfo;
250  finfo.nSizeX = ni;
251  finfo.nSizeY = nj;
252  finfo.nBands = nplanes;
253  finfo.eCellType = t;
254  finfo.nCompressionRate = compression_ratio;
255  finfo.eCellSizeUnits = ECW_CELL_UNITS_METERS;
256  finfo.fCellIncrementX = 1.0;
257  finfo.fCellIncrementY = 1.0;
258  finfo.fOriginX = 0.0;
259  finfo.fOriginY = 0.0;
260  finfo.szDatum = "RAW";
261  finfo.szProjection = "RAW";
262  finfo.fCWRotationDegrees = 0.0;
263  if (nplanes ==1)
264  finfo.eColorSpace = NCSCS_GREYSCALE;
265  else if (nplanes ==3)
266  finfo.eColorSpace = NCSCS_sRGB;
267  else {
268  delete mFileResource;
269  mFileResource = 0;
270  }
271  Error = mFileResource->SetFileInfo(finfo);
272  if (Error != NCS_SUCCESS) {
273  if (mFileResource)
274  delete mFileResource;
275  mFileResource = 0;
276  }
277  Error = mStr->Open(vs, true);
278  if (Error != NCS_SUCCESS) {
279  if (mFileResource)
280  delete mFileResource;
281  mFileResource = 0;
282  }
283  CNCSJP2FileView* fview = static_cast<CNCSJP2FileView*>(mFileResource);
284  Error = fview->Open(static_cast<CNCSJPCIOStream*>(mStr));
285  if (Error != NCS_SUCCESS) {
286  if (mFileResource)
287  delete mFileResource;
288  mFileResource = 0;
289  return;
290  }
291 }
292 
294 {
295  if ( mFileResource ) {
296  mFileResource->Close( true );
297  }
298  if (mStr)
299  delete mStr;
300  if (mBandinfo)
301  delete mBandinfo;
302  if (mFinfo)
303  delete mFinfo;
304 }
305 
306 unsigned vil_j2k_image::nplanes() const
307 {
308  assert( mFileResource );
309  return mFileResource->GetFileInfo()->nBands;
310 }
311 
312 unsigned vil_j2k_image::ni() const
313 {
314  assert( mFileResource );
315  return mFileResource->GetFileInfo()->nSizeX;
316 }
317 
318 unsigned vil_j2k_image::nj() const
319 {
320  assert( mFileResource );
321  return mFileResource->GetFileInfo()->nSizeY;
322 }
323 
325 {
326  assert( mFileResource );
327  return convertType( mFileResource->GetFileInfo()->eCellType );
328 }
329 
330 char const* vil_j2k_image::file_format() const
331 {
332  return "j2k";
333 }
334 
337  unsigned num_samples,
338  unsigned line0,
339  unsigned numLines,
340  double i_factor,
341  double j_factor) const
342 {
343  return get_copy_view_decimated_by_size(sample0,
344  num_samples,
345  line0,
346  numLines,
347  (unsigned int)(((double)num_samples)/i_factor),
348  (unsigned int)(((double)numLines)/j_factor));
349 }
350 
353  unsigned num_samples,
354  unsigned line0,
355  unsigned numLines,
356  unsigned int output_width,
357  unsigned int output_height) const
358 {
359  if ( !( mFileResource ) ||
360  !( ( sample0 + num_samples - 1 ) < ni() &&
361  ( line0 + numLines - 1 ) < nj() ) )
362  {
363  return 0;
364  }
365 
366  //we want all bands mapped in the same order as they come in the input file
367  //eg. bandMap = {0,1,2,3...nBands}
368  INT32 nBands = nplanes();
369  INT32* bandMap = (INT32*) std::malloc(sizeof(UINT32) * nBands );
370  for ( int i = 0 ; i < nBands ; i++ ) { bandMap[i] = i; }
371 
372  //this guards us from returning an image that is too big for the computer's memory
373  //(or would take too long to download in the remote case).
374  //We don't want infinite hangs or application crashes.
375  unsigned int maxDim = mRemoteFile ? mMaxRemoteDimension : mMaxLocalDimension;
376  if ( output_width > maxDim || output_height > maxDim ) {
377  unsigned int biggestDim = (std::max)( output_width, output_height );
378  double zoomFactor = ((double)maxDim) / ((double)biggestDim);
379  output_width = (unsigned int) ( ((double)output_width) * zoomFactor );
380  output_height = (unsigned int) ( ((double)output_height) * zoomFactor );
381  }
382 
383  //set the view to be that specified by the function's input parameters
384  //note that we don't want ECW to do any scaling for us. That's why
385  //the box created by (sample0,line0) and (sample0+num_samples-1,line0+numLines-1) is made to be exactly num_samplesXnumLines.
386 
387  NCSError setViewError = mFileResource->SetView( nBands, bandMap, output_width, output_height,
388  (INT32)sample0, (INT32)line0, (INT32)(sample0+num_samples-1), (INT32)(line0+numLines-1) );
389  if ( setViewError != NCS_SUCCESS ) {
390  free( bandMap );
391  return 0;
392  }
393 
394  //number of samples times the bytes per sample in each band
395  double bitsPerSample = mFileResource->GetFileInfo()->pBands[0].nBits;
396  unsigned int bytesPerSample = (unsigned int) std::ceil( bitsPerSample / 8.0 );
397  unsigned int singleBandLineSizeBytes = output_width * bytesPerSample;
398  unsigned int allBandLineSizeBytes = singleBandLineSizeBytes * nBands;
399  unsigned int dataPtrSizeBytes = allBandLineSizeBytes * output_height;
400  //void* data_ptr = std::malloc( dataPtrSizeBytes );
401  vil_memory_chunk_sptr data_ptr = new vil_memory_chunk( dataPtrSizeBytes, convertType( mFileResource->GetFileInfo()->eCellType ) );
402  void** linePtrPtr = (void**)std::malloc( nBands * sizeof( int* /*all pointers have same size, so eg char* would work too*/ ) );
403  //now read all the lines that we want
404  for ( unsigned int currLine = 0 ; currLine < output_height ; currLine++ ) {
405  for (int currBand = 0 ; currBand < nBands ; currBand++ ) {
406  linePtrPtr[currBand] = (void*) ( ((char*)data_ptr->data()) + currLine * allBandLineSizeBytes + currBand * singleBandLineSizeBytes );
407  }
408  NCSEcwReadStatus readStatus = mFileResource->ReadLineBIL( mFileResource->GetFileInfo()->eCellType, nBands, linePtrPtr, 0);
409  if ( readStatus != NCSECW_READ_OK ) {
410  free( bandMap );
411  free( linePtrPtr );
412  return 0;
413  }
414  }
415 
416  //free our temp resources
417  free( bandMap );
418  free( linePtrPtr );
419 
420  vil_image_view_base_sptr view = 0;
421  //now create our vil_image_view
422  //note that float and double are defaulted since the J2K SDK doesn't
423  //implement these types properly
424  switch ( vil_pixel_format_component_format( data_ptr->pixel_format() ) )
425  {
426 #define macro( F, T ) \
427  case F: \
428  view = new vil_image_view< T > ( data_ptr, reinterpret_cast<T*>(data_ptr->data()), \
429  output_width, output_height, nBands, 1, output_width*nBands, output_width); \
430  break
431  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte );
432  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte );
433  macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 );
434  macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 );
435  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 );
436  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 );
437  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 );
438  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 );
439  macro(VIL_PIXEL_FORMAT_BOOL , bool );
440 #undef macro
441  default:
442  std::cerr << "Pixel format not supported by ERMapper SDK\n";
443  assert( 0 );
444  break;
445  }
446 
447  return view;
448 }
449 
451  unsigned num_samples,
452  unsigned line0,
453  unsigned numLines ) const
454 {
455  return get_copy_view_decimated( sample0, num_samples, line0, numLines, 1.0, 1.0 );
456 }
457 
459 {
460 #undef max
461  setMaxImageDimension( std::numeric_limits< unsigned int >::max(), remote );
462 }
463 
464 void vil_j2k_image::setMaxImageDimension( unsigned int widthOrHeight, bool remote )
465 {
466  if ( remote ) {
467  mMaxRemoteDimension = widthOrHeight;
468  } else {
469  mMaxLocalDimension = widthOrHeight;
470  }
471 }
472 
474  unsigned i0, unsigned ni,
475  unsigned j0, unsigned nj,
476  double i_factor, double j_factor )
477 {
478  vil_j2k_image* j2k_image = new vil_j2k_image(vs);
479  //remove limit by default, since vil is not typically used remotely
480  //but more commonly with large image files - JLM Jan 07, 2012
481  j2k_image->unsetMaxImageDimension();
482  vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated(i0, ni, j0, nj, i_factor, j_factor);
483  delete j2k_image;
484  return view;
485 }
486 
489  unsigned i0, unsigned ni,
490  unsigned j0, unsigned nj,
491  unsigned int output_width,
492  unsigned int output_height )
493 {
494  vil_j2k_image* j2k_image = new vil_j2k_image(vs);
495  vil_image_view_base_sptr view = j2k_image->get_copy_view_decimated_by_size(i0, ni, j0, nj, output_width, output_height);
496  delete j2k_image;
497  return view;
498 }
499 
500 template < class T >
501 static bool write_line_BIL(vil_memory_chunk_sptr& chunk,
502  unsigned ni, unsigned nplanes, unsigned istep,
503  unsigned planestep, unsigned bytes_per_pixel,
504  CNCSFile* f_resource, NCSEcwCellType t)
505 {
506  T* cdata = reinterpret_cast<T*>(chunk->data());
507  T** line_ptr = new T*[nplanes];
508  for (unsigned p = 0; p<nplanes; ++p)
509  line_ptr[p] = new T[ni*bytes_per_pixel];
510 
511  for (unsigned p = 0; p<nplanes; ++p) {
512  T* wline = line_ptr[p];
513  for (unsigned i = 0; i<ni; ++i) {
514  *(wline+i) = *(cdata+ i*istep + p*planestep);
515  }
516  }
517  bool good = true;
518  void ** outbuf = reinterpret_cast<void**>(line_ptr);
519  CNCSError writeError = f_resource->WriteLineBIL(t, nplanes, outbuf);
520  if ( writeError != NCS_SUCCESS ) good = false;
521 
522  for (unsigned p = 0; p<nplanes; ++p)
523  delete [] line_ptr[p];
524  delete [] line_ptr;
525  return good;
526 }
527 
528 
529 //: JPEG2K compress by inserting an image row (line) at a time
530 // When the full image has been inserted, call put_line with
531 // image_row == nj(). This call causes the resource to be closed
532 // and is no longer valid. The lines must be inserted in strict row order.
533 bool
535 {
536  if (!mFileResource)
537  return false;
538  vil_pixel_format format = this->pixel_format();
539  unsigned ni = this->ni(), nj = this->nj(), nplanes = this->nplanes();
540  if (line_index_>=nj) {
541  mFileResource->Close(true);
542  if (mFileResource)
543  delete mFileResource;
544  mFileResource = 0;
545  return true;
546  }
547  unsigned bytes_per_pixel = 0;
548  NCSEcwCellType t = convertType(format);
549  vil_memory_chunk_sptr chunk;
550  //now write out the image line
551  //note that float and double are defaulted since the J2K SDK doesn't
552  //implement these types properly
553  switch ( vil_pixel_format_component_format( format ) )
554  {
555 #define macro( F, T )\
556  case F: {\
557  bytes_per_pixel = sizeof(T); \
558  const vil_image_view<T>& view = static_cast<const vil_image_view<T>&>(im); \
559  chunk = view.memory_chunk(); \
560  if (!write_line_BIL<T>(chunk, ni, nplanes, view.istep(), view.planestep(),\
561  bytes_per_pixel, mFileResource, t)) \
562  return false; \
563  } \
564  break
565  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte );
566  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte );
567  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 );
568  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 );
569  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 );
570  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 );
571  macro(VIL_PIXEL_FORMAT_BOOL , bool );
572 #undef macro
573  default:
574  std::cerr << "Pixel format not supported by ERMapper SDK\n";
575  assert( 0 );
576  break;
577  }
578  ++line_index_;
579  return true;
580 }
581 
582 //: JPEG2K compress the view and of the full image and insert in resource
583 // The file is closed after putting the view into the resource
584 // and becomes an invalid resource.
585 bool vil_j2k_image::
587 {
588  if (!this->view_fits(im, 0, 0))
589  return false;
590  if (!mFileResource)
591  return false;
592  unsigned ni= im.ni(), nj = im.nj();
593  vil_image_resource_sptr mem_res =
596  for (unsigned j = 0; j<nj; ++j) {
597  view = mem_res->get_copy_view(0, ni, j, 1);
598  if (!this->put_line(*view)) return false;
599  }
600  return true;
601 }
602 
603 //: Check that a view will fit into the data at the given offset.
604 bool vil_j2k_image::
605 view_fits(const vil_image_view_base& im, unsigned i0, unsigned j0)
606 {
607  unsigned ni_view = im.ni(), nj_view = im.nj(), nplanes_view = im.nplanes();
608  return i0+1 < ni_view
609  && j0+1 < nj_view
610  && ni_view <= this->ni()
611  && nj_view <= this->nj()
612  && nplanes_view <= this->nplanes();
613 }
614 
615 //:
616 // Encode an entire image by loading the input resource from stream
617 // and compressing the input line by line by extracting an image view
618 // of a block of lines at a time, thus works for arbitrarily large images.
619 // The num_lines_block parameter is the number of image rows in the
620 // block which is read into memory from the resource
622  const char* out_filename,
623  unsigned compression_ratio,
624  unsigned num_lines_block,
625  bool verbose)
626 {
628  if (!in_res)
629  return false;
630  unsigned ni = in_res->ni(), nj = in_res->nj(), nplanes = in_res->nplanes();
631  vil_pixel_format format = in_res->pixel_format();
632  vil_stream* os = vil_open(out_filename, "w");
633  if (!vs) return false;
635  fmt.set_compression_ratio(compression_ratio);
637  format);
638  if (!res) return false;
639  vil_j2k_image* j2k_img = reinterpret_cast<vil_j2k_image*>(res.ptr());
640 
641  //number of full blocks in image height
642  unsigned n_blocks = nj/num_lines_block;
643  unsigned jb = 0;
644  for (unsigned b = 0; b<n_blocks; b++, jb += num_lines_block)
645  {
646  // read a block from the file: width = ni, height = num_lines_block
647  vil_image_view_base_sptr block_view = in_res->get_view(0, ni, jb, num_lines_block);
648  if (!block_view) return false;
649 
650  //wrap the view in a memory resident resource
651  vil_image_resource_sptr block_res =
652  vil_new_image_resource_of_view(*block_view);
653 
654  //compress the block, line by line
655  for (unsigned j = 0; j<num_lines_block; ++j) {
656  vil_image_view_base_sptr line_view =
657  block_res->get_copy_view(0, ni, j, 1);
658  if (!j2k_img->put_line(*line_view)) return false;
659  if (verbose)
660  if (j%100 == 0) //output a dot every 100 lines
661  std::cout << '.';
662  }
663  }
664  //output the remaining lines left over after loading block-sized chunks
665  unsigned remaining_lines = nj-jb;
666  if (remaining_lines) {
667  vil_image_view_base_sptr residual_view =
668  in_res->get_view(0, ni, jb, remaining_lines);
669  vil_image_resource_sptr residual_res =
670  vil_new_image_resource_of_view(*residual_view);
672  for (unsigned j = 0; j<remaining_lines; ++j) {
673  view = residual_res->get_copy_view(0, ni, j, 1);
674  if (!j2k_img->put_line(*view)) return false;
675  if (verbose)
676  if (j%100 == 0) //output a dot every 100 lines
677  std::cout << '.';
678  }
679  }
680  if (verbose) std::cout << '\n';
681  return true;
682 }
683 
684 bool vil_j2k_image::s_encode_jpeg2000(const char* in_filename,
685  const char* out_filename,
686  unsigned compression_ratio,
687  unsigned num_lines_block,
688  bool verbose )
689 {
690  vil_stream* vs = vil_open(in_filename);
691  vs->ref();
692  bool success =
693  vil_j2k_image::s_encode_jpeg2000(vs, out_filename,
694  compression_ratio,
695  num_lines_block,
696  verbose);
697  vs->unref();
698  return success;
699 }
virtual vil_image_resource_sptr make_input_image(vil_stream *vs)
Attempt to make a generic_image which will read from vil_stream vs.
virtual bool view_fits(const vil_image_view_base &im, unsigned i0, unsigned j0)
Check that a view will fit into the data at the given offset.
An abstract base class of smart pointers to actual image data in memory.
vil_pixel_format
Describes the type of the concrete data.
vil_pixel_format vil_pixel_format_component_format(enum vil_pixel_format f)
Return the number of components in pixel format f.
vil_image_resource_sptr vil_load_image_resource_raw(vil_stream *, bool verbose=true)
Load from a stream.
Definition: vil_load.cxx:19
static vil_image_view_base_sptr s_decode_jpeg_2000_by_size(vil_stream *vs, unsigned i0, unsigned ni, unsigned j0, unsigned nj, unsigned int output_width, unsigned int output_height)
vil_image_view_base_sptr get_copy_view() const
unsigned int mMaxLocalDimension
vil_j2k_image(const std::string &fileOrUrl)
std::complex<float> is a scalar for vil's purposes.
virtual unsigned nj() const
Dimensions: Planes x ni x nj.
NCSFileBandInfo bandInfo(const vil_pixel_format &vilType)
Class capable of reading JPEG2000 Part I files and ECW (ER Mapper's proprietary format) image files.
Definition: vil_j2k_image.h:63
bool is_valid() const
Call this after construction to see if you can get valid data from me.
CNCSJPCVilIOStream * mStr
The ermapper stream.
unsigned int mMaxRemoteDimension
Same as.
virtual unsigned nplanes() const
Dimensions: planes x width x height x components.
vil_j2k: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of Stellar Science Ltd.
vil_stream * vil_open(char const *what, char const *how)
make a vil_stream from a filename, an URL, etc.
Definition: vil_open.cxx:18
void unsetMaxImageDimension(bool remote=false)
Call this if you don't want get_copy_view() to do size checking.
virtual unsigned ni() const
Dimensions: Planes x ni x nj.
static bool s_encode_jpeg2000(vil_stream *vs, const char *out_filename, unsigned compression_ratio=1, unsigned num_lines_block=1024, bool verbose=false)
Encode an entire image by loading the input resource from stream and compressing the input line by li...
read an image from a file
NCSEcwCellType convertType(const vil_pixel_format &vilType)
virtual char const * tag() const
Return a character string which uniquely identifies this format.
unsigned ni() const
Width.
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
unsigned nj() const
Height.
CNCSFile * mFileResource
The ermapper file.
virtual bool put_view(const vil_image_view_base &im)
JPEG2K compress the data from the full image view and insert in resource.
void set_compression_ratio(unsigned ratio)
This compression ratio is set as a target for the ermapper compression algorithm. The default is loss...
Definition: vil_j2k_image.h:33
Abstract representation of an image source or image destination.
#define macro(F, T)
void ref()
up/down the reference count.
Definition: vil_stream.h:45
virtual CNCSError Open(vil_stream *stream, bool bWrite=false)
Pass me the stream you want me to wrap.
A base class reference-counting view of some image data.
Ref. counted block of data on the heap.
virtual enum vil_pixel_format pixel_format() const
Pixel Format.
void unref()
Definition: vil_stream.cxx:31
Make a new image.
virtual vil_image_view_base_sptr get_copy_view_decimated(unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor) const
bool put_line(const vil_image_view_base &im)
JPEG2K compress by inserting an image row (line) at a time.
NCSFileBandInfo * mBandinfo
band information array.
void setMaxImageDimension(unsigned int widthOrHeight, bool remote=false)
When calling get_copy_view(), the function will scale down the output image_view so that neither dime...
unsigned nplanes() const
Number of planes.
make a vil_stream from a filename, an URL, etc.
vil_image_resource_sptr vil_new_image_resource_of_view(vil_image_view_base const &view)
Make a new image resource that is a wrapper on an existing view's data.
Definition: vil_new.cxx:62
virtual vil_image_resource_sptr make_output_image(vil_stream *vs, unsigned ni, unsigned nj, unsigned nplanes, enum vil_pixel_format format)
Make a "generic_image" on which put_section may be applied.
Wrapper class that allows you to effectively "convert" a vil_stream to a CNCSJPCIOStream.
char const * file_format() const
returns j2k.
virtual vil_image_view_base_sptr get_copy_view_decimated_by_size(unsigned i0, unsigned ni, unsigned j0, unsigned nj, unsigned int output_width, unsigned int output_height) const
static vil_image_view_base_sptr s_decode_jpeg_2000(vil_stream *vs, unsigned i0, unsigned ni, unsigned j0, unsigned nj, double i_factor, double j_factor)
Static function that can be used to decode a JPEG2000 codestream or file (jp2 file).
bool mRemoteFile
file is remote.
unsigned line_index_
the current line being written for compression.
T * ptr() const
These methods all return the raw/dumb pointer.
NCSFileViewFileInfoEx * mFinfo
the file information block.
std::complex<double> is a scalar for vil's purposes.
unsigned compression_ratio_
Definition: vil_j2k_image.h:36